C ++: 易错点总结一(sizeof、数组大小、同名变量、无符号与有符号类型转换)
1. ‘sizeof’ 的实质
sizeof可以接受变量和数据类型,并以字节为单位返回该类型所占内存的大小。
使用方式:1. sizeof(数据类型或变量) 2. sizeof 变量
sizeof不是一个函数(一般函数无法接受数据类型作为参数;函数只能通过括号传递参数,而sizeof可以通过空格加参数)。
sizeof可以返回内置数据类型的大小、自定义数据类型的大小、数组的size、指针的大小、有返回值的函数调用(sizeof(func()),func()返回int)等。
sizeof是在编译阶段处理的。
int a = 0; cout<<sizeof(a=3)<<endl; cout<<a<<endl;
上述代码最后的输出为0;因为sizeof括号内部的表达式不会被编译成二进制,只是在编译阶段就翻译成数据类型,在运行时不会再运算。
int id[sizeof(unsigned long)];
这种写法也是对的。
2. 数组的大小
void fun (int * arr){ sizeof(arr); //指针大小:4 } int main(){ int arr[5]; sizeof(arr); // 数组大小:5 * 4 = 20 fun(arr);
int* d = new [10];
sizeof(d); // 指针大小,因为new是运行时确认的,编译时只有指针的大小。
double* (*a)[3][6];
cout<<sizeof(a)<<endl; // 4,指针
cout<<sizeof(*a)<<endl; // 72,二维数组
cout<<sizeof(**a)<<endl; // 24,一维数组
cout<<sizeof(***a)<<endl; // 4,数组指针
cout<<sizeof(****a)<<endl; // 8,第一个元素大小,相当于a[0][0]
// *******字符串大小*********
char a[] = "abcdef";
char b[20] = "abcdef";
string s = "abcdef";
cout<<strlen(a)<<endl; // 6,字符串长度
cout<<sizeof(a)<<endl; // 7,字符串容量
cout<<sizeof(s)<<endl; // 12, 这里不代表字符串的长度,而是string类的大小
a[1] = '';
cout<<strlen(a)<<endl; // 1
cout<<sizeof(a)<<endl; // 7,sizeof是恒定的
return 0; }
Note:sizeof是编译时计算出的大小,sizeof注意数据类型的表现形式要一致。
3. 多维数组
int arr[5][20] printf("%p %p", arr, arr + 1); // arr + 1比arr 多20 * 4 = 80 int** num = (int**)arr; printf("%p %p", num, num + 1); // num + 1 比 num多 4
二维指针传参
高维数组传参必须指定第二个维度以后的维度大小
不能写成: func(int **arr)
func(int arr[][20])
func(int (* arr)[20])
高维数组的地址存储,计算机底层没有高维数组的概念。
4. 全局和局部变量同名
全局变量和局部变量同名,优先引用局部变量,除非在变量前面加::指定为全局变量,::符号只在C++中有。看以下例子
int x = 3; int y = 5; int main() { { int x = 0; x = 3 + 1; int y = 0; ::y = 5 + 1; } std::cout << "x=" << x << std::endl; std::cout << "y=" << y << std::endl; }
输出:
x=3 // x没有加::,优先修改局部变量
y=6 // y加::,修改全局变量
5. 无符号到有符号的类型转换
概念:
负数在计算机中是以补码的形式存在的。
例如-1:二进制表示为:1111 1111 1111 1111
源码/反码/补码:
源码:最高位为符号位,1为负0为正,其余位为十进制的二进制表示
反码:除了最高位的符号位其余取反
补码:在反码的基础上,最低位加1
在既有有符号位又有无符号的运算中,有符号的数值被强制转换为无符号位的数值(二进制不变,所以最高位不作为符号位了)