IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++入门——变量 -> 正文阅读

[C++知识库]C++入门——变量

变量

全局变量与静态变量

相同点

总的来说,它们的相同点是都保留在静态存储区,生命期与程序生命期相同。

不同点

  1. 总的来说,它们的不同点是,全局变量具有全局作用域,静态变量具有文件作用域。

  2. 静态局部变量具有局部作用域,只被初始化一次,自从第一次被初始化,直到程序运行结束都一直存在。它和全局变量的区别在于,全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见

  3. 静态全局变量也具有全局作用域,它与全局变量的区别在于,如果程序包含多个文件,它作用于定义它的文件里,不能作用到其他文件里,即被static关键字修饰过的变量具有文件作用于这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量

  4. 把局部变量改变为静态变量后是改变了它的存储方式,即改变了它的生存期;把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围

局部变量与全局变量

局部变量可以与全局变量重名,但是局部变量会屏蔽全局变量。要使用全局变量,需要使用操作符::

对于有些编译器,在同一个函数体内可以定义多个同名的局部变量。例如,在两个循环体内都定义一个同名的局部变量,而那个局部变量的作用域就在那个循环体内

全局变量与局部变量的区别:

  1. 全局变量的作用域为程序块,而局部变量的作用域为当前函数

  2. 内存存储方式不同,全局变量分配在全局数据区,后者分配在栈区

  3. 生命周期不同。全局变量随主程序创建而创建,随主程序销毁而销毁,局部变量在局部函数内部,甚至局部循环体等内部存在,退出就不存在了

  4. 使用方式不同。通过声明为全局变量,程序的各个部分都可以用到,而局部变量只能在局部使用

但是,局部变量不可以赋值为同名的全局变量,例如:

#include <stdio.h>
int i = 1;
int main()
{
    int i = i;
    printf("%d\n", i);
    return 0;
}

程序的输出结果为:

-858993460

上述代码合法,有的编译器编译也能通过,但是不合理。int i = ii变量从声明那一刻开始就是可见的,main()函数里的i不是i,因为它和main()函数外的i无关,而是一个未定义的值,所以输出就是一个随机值了

一些复杂的变量声明

  1. 一个有10个指针的数组,数组中指针指向一个整型数。int *a[10];

  2. 一个指向有10个整型数数组的指针。int (*a)[10];

  3. 一个指向函数的指针,该函数有一个整型参数并返回一个整数。int (*a)(int);

  4. 一个有10个指针的数组,该指针指向一个函数,该函数有一个整型参数并返回一个整型数。int (*a[10])(int);

在C语言中,每个变量声明都由两个部分组成:一个类型和一组具有特定格式的,期望用来对该类型求值的表达式。例如,float *g(), (*h)(),该语句表示*g()(*h)()都是float表达式。由于()*优先级更高,绑定的更紧密,所以*g()*(g())表示的意义相同,即g是一个返回float指针的函数,而h是一个指向返回float的函数的指针

还有一些更复杂的声明方式:

  1. (*(void(*)())0)()
    该声明表示硬件会调用地址为0处的子程序,但如果写成是(*0)()并不符合要求,因为*运算要求必须有一个指针作为它的操作数,而不能是数字。而且,这个操作数必须是一个指向函数的指针,以保证*的结果可以被调用,所以此时需要将0转换为一个可以描述“指向一个返回void的函数的指针”的类型,即(void(*)())0

  2. void *(*(*fp1)(int))[10];
    可以分解为如下两个表达式:
    1)p = (*fp1)(int)
    2)void *(*p)[10]
    第一个表达式中,fp1是一个函数的指针,这个函数的参数为int,函数的返回值为p;第二个表达式中,p是一个指向有10个元素的数组的指针,这个数组中元素的类型为void*(指向void指针)。综上,fp1是一个函数的指针,它指向的函数有一个int参数,这个函数的返回值是一个指针,这个指针指向一个有10个元素的数组,而且数组中每个元素都是void*

  3. float (*(*fp2)(int, int, int))(int);
    可以分解为如下两个表达式:
    1)p = (*fp2)(int, int, int)
    2)float (*p)(int)
    第一个表达式中,fp2是一个指针,这个指针指向一个函数,这个函数有3个int类型的参数,这个函数的返回值为p;第二个表达式中,p也是一个指针,指向一个函数,并且这个函数的参数为int,返回值为float。综上,fp2是一个指向函数的指针,函数有3个int类型的参数,函数的返回值是一个函数的指针(这个函数的参数为int,返回值为float

C语言中各种变量默认初始值

全局变量放在内存的全局数据区,由编译器建立,如果在定义的时候不做初始化,则系统将自动为其初始化,数值型为0,字符型为NULL,指针变量也被赋值为NULL。静态变量的情况与全局变量类似。而非静态局部变量如果不显式初始化,那么其内容是不可预料的,将是随机数,会很危险,对系统造成非常大的安全隐患

类型转换

在C/C++中,常用的数据类型有charucharshortushortintuintlongulongfloatdouble。这些数据类型所能表示的范围也是不同的。那么当这些不同的数据类型参与运算的时候,就带来了类型转换问题。

算术运算过程中的类型转换

当参与运算的表达式中有不同的数据类型时,在运算的时候会进行类型隐式转化,遵循以下规则:

  1. 整数提升。如果参与运算的表达式中没有比int更高的类型,那么,运算的表达式都会隐式转换为int,然后进行运算

  2. 类型对齐。把所有参与运算的表达式隐式转换为占用空间最大的数据类型

  3. 当无符号数与有符号数类型进行混合运算时,有符号数会隐式转换为无符号数

综上,类型隐式转换的规则如下:

(char, uchar, short, ushort)-->int->uint-->long-->ulong-->float-->double

赋值运算过程中的类型转换

  1. 普通的两个变量赋值,以左值为准

  2. 函数参数的传递,其实也就是把实参的值赋给形参,以形参的类型为准

  3. 赋值运算,其实就是将函数运算的结果赋值给返回值,以返回值类型为准

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-07-17 11:43:20  更:2021-07-17 11:44:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 0:49:34-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码