数组: 相同数据类型的集合,并且是一块连续的内存单元
数组聚合类型:初始化只有一次。
arr1[5] 如果数组只进行了声明,那么初值为随机值!!
arr2[5]={1,2,3} 如果局部初始化,其他元素值为0!! 1 2 3 0 0
arr3[5]={} 0 0 0 0 0
arr数组名代表数组的首地址;
二维数组
int brr2[3][3] = {1,2,3,4,5,6,7,8,9};
int brr3[3][3] = {1,2,3,4,5,6};//默认值为0
int brr4[][3] = {1,2,3,4,5,6};//二维数组定义的时候可以省略行
sizeof strlen
取别 :sizeof 包含\0; strlen 遇到\0停止
int len = sizeof(arr)/sizeof(arr[0]); //计算数组长度
char crr[5] = {'a','b','c','d'}; sizeof(crr)/sizeof(crr[0]) 5
char crr2[] = {'a','b','c','d','e'}; sizeof(crr2)/sizeof(crr2[0]) 5
char crr5[] = "abcde";//默认加\0 sizeof(crr5)/sizeof(crr5[0]) 6
sizeof strlen
char str[100] = "abcdef"; 100 6
char str2[] = "abcdef"; 7 6
char *str3 = "abcdef"; 4 6
char str4[100] = "abcdef\0xyz"; 100 6
char str5[] = "abcdef\0xyz"; 11 6
char *str6 = "abcdef\0xyz"; 4 6
char str7[] = "abcdef\n\0"; 9 7
char *str8 = "abcdef\n\0"; 4 7
指针
指针是程序数据在内存中的地址,而指针变量是用来保存这些地址的变量。
C语言中的一切函数调用中,值传递都是“按值传递”的,如果我们要在函数中修改被传递过来的对象,就必须通过这个对象的指针来完成。
由于内存中的每一个字节都有一个唯一的编号,因此,在程序中使用的变量,常量,甚至数函数等数据,当他们被载入到内存中后,都有自己唯一的一个编号,这个编号就是这个数据的地址。指针就是这样形成的。
sizeof(指针): 4 不管什么指针
值永远为4 int * char * double*
int *p=&a;//指针用来保存地址
用来保存 指针 的变量,就是指针变量。如果指针变量p1保存了变量 num的地址,则就说:p1指向了变量num,也可以说p1指向了num所在的内存块 ,这种指向关系,在图中一般用 箭头表示。
上图中,指针变量p1指向了num所在的内存块 ,即从地址0028FF40开始的4个byte 的内存块。
定义指针变量
C语言中,定义变量时,在变量名 前 写一个 * 星号,这个变量就变成了对应变量类型的指针变量。必要时要加( ) 来避免优先级的问题。
取地址
既然有了指针变量,那就得让他保存其它变量的地址,使用& 运算符取得一个变量的地址。
特殊的情况,他们并不一定需要使用&取地址:
- 数组名的值就是这个数组的第一个元素的地址。
- 函数名的值就是这个函数的地址。
- 字符串字面值常量作为右值时,就是这个字符串对应的字符数组的名称,也就是这个字符串在内存中的地址。
解地址
我们需要一个数据的指针变量干什么?当然使用通过它来操作(读/写)它指向的数据啦。对一个指针解地址,就可以取到这个内存数据,解地址 的写法,就是在指针的前面加一个*号。
解指针的实质是:从指针指向的内存块中取出这个内存数据。
空指针
指向空,或者说不指向任何东西。在C语言中,我们让指针变量赋值为NULL表示一个空指针,而C语言中,NULL实质是 ((void*)0) , 在C++中,NULL实质是0。
换种说法:任何程序数据都不会存储在地址为0的内存块中,它是被操作系统预留的内存块。