1、
普通全局变量——作用域是整个源程序(含有多个源文件,在各个源文件中都有效)
static全局变量——作用域在当前源文件
2、
引用
(1)申明引用的同时必须要初始化
(2)引用变量是目标变量的一个别名,相当于目标变量,只是名字不同
(3)申明一个引用不是定义了新的变量,只是目标变量的一个别名,引用本身不是一种数据类型,因此不占存储单元,系统也不会给引用分配存储单元
(4)对引用求地址,就是对目标变量求地址,&a == &i
(5)在被调函数中交换主调函数的两个值,常用方法传递变量地址,第二种就是传递引用
int i =3;
int & a = i; //这里a就是变量i,printf(i) == printf(a),printf(&a) == printf(&i)
//被调函数:
void f(int &a, int &b)
{
int t = a;
a = b;
b = t;
}
//主调函数:
main
{
int a = 1, b = 2;
f(a, b); //实参已经交换
}
但如果局部变量设定为静态局部变量:
int &f()
{
static int i = 10; //静态局部变量,在全局区,静态变量等到整个程序运行结束后才会释放
return i;
}
main()
{
int &p = f(); //返回的静态变量要等到整个程序运行结束才释放
cout << p << endl; //10,
cout << p << endl; //10
}
(6)引用一旦初始化就不可以更改
int i = 10;
int &b = i; //现在b就是变量i的别名
int j = 100;
b = j; //并没有把b转变为变量j的别名,这里相当于把100赋值给b,又因为b是变量i的别名,也就相当于把100赋值给i
(7)引用作为函数返回值
不要返回局部变量的引用:
int & f()
{
int i = 10;
return i; //返回局部变量引用
}
main()
{
int &p = f(); //返回局部变量引用
cout << p << endl; //10,函数运行结束局部变量销毁,这里编译器第一次保留了返回值
cout << p << endl; //1013313,第二次打印乱码,编译器不再保留数值
}
但如果局部变量设定为静态局部变量:
int &f()
{
static int i = 10; //静态局部变量,在全局区,静态变量等到整个程序运行结束后才会释放
return i;
}
main()
{
int &p = f(); //返回的静态变量要等到整个程序运行结束才释放
cout << p << endl; //10,
cout << p << endl; //10
}
(8)如果函数的返回值是引用,这个函数可以作为左值
int &f()
{
static int i = 10;
return i;
}
main()
{
int &p = f(); //函数返回引用给p,此时引用p是变量i的一个别名
cout << p << endl; //10
f() = 100; //函数返回变量i值,这时变量i又被赋值100,又因为上面p是变量i的别名,等于p被赋值100
cout << p << endl; //100
}
(9)引用的本质是指针常量,地址不可变,值可变
int a = 10;
int &b = a; //实际是int * const b = &a;
b = 20; //实际是*b = 20;
(10)常量引用
int i = 10;
int &p = i; //给引用赋的是变量,如果int &p = 10; 直接赋常量报错
const int &p = 10; //常量引用可以直接赋值,编译器做了一个默认操作,int tmp = 10;然后const int &p = tmp; 而且常量引用值是不可以修改的,因为常量引用本质是常量指针常量,const int * const p = &tmp;
3、
switch语句中的case后面为常量或者常量表达式,且是整数、枚举、字符
4、
int * f(); //指针函数,返回的是Int型的指针
int (*f)(); //函数指针,返回的是一个int型的值,但这个函数是一个指向函数的指针,如果有另一个函数g()赋给f时,可以f = g,也可以f=&g。因为函数名也是函数的地址。
5、
char * p[3] //指针数组,每个元素都是char *类型的字符串
char (*p)[3] //数组指针,相当于char p[][3]二维数组