创建一个整型数组
int a[] = {1,2,3,4};
1.sizeof(数组名)表整个数组的大小。4*4=16
printf("%d\n",sizeof(a));//4*4=16
2.a表示首元素地址,a+0还是首元素地址。地址大小为4或8字节
printf("%d\n",sizeof(a+0));//4/8
3.*a表示首元素,整型一维数组中每个元素都是4字节
printf("%d\n",sizeof(*a));//4
4.a+1表示跳过首元素,指向第二个元素地址。地址大小为4或8字节
printf("%d\n",sizeof(a+1));//4/8
5.a[1]表示第二个元素,整型一维数组中每个元素都是4字节
printf("%d\n",sizeof(a[1]));//4
6.&a是整个数组的地址,地址大小为4或8字节
printf("%d\n",sizeof(&a));//4/8
7.sizeof( ∗ * ∗&a)–>sizeof(a)–>整个数组大小,4*4=16
∗ * ∗和&互为逆运算,会抵消
printf("%d\n",sizeof(*&a));//16
8.&a表示整个数组地址,&a+1跳过的是整个数组,得到的是地址,地址大小为4或8字节
printf("%d\n",sizeof(&a+1));//4/8
9.&a[0]表示首元素地址,地址大小为4或8字节
printf("%d\n",sizeof(&a[0]));//4/8
10.&a[0]+1表示跳过首元素,得到第二个元素地址,地址大小为4或8字节
printf("%d\n",sizeof(&a[0]+1));//4/8
创建一个由多个独立字符组成的字符数组
char arr[] = {'a','b','c','d','e','f'};
1.sizeof(arr)计算整个数组大小,1*6=6
printf("%d\n", sizeof(arr));//6
2.arr表示首元素地址,arr+0还是首元素地址,4/8
printf("%d\n", sizeof(arr+0));//4/8
3. ∗ * ∗arr表示首元素,字符型一维数组中每个元素大小都为1字节
printf("%d\n", sizeof(*arr));//1
4.arr[1]表示数组中第二个元素,字符型一维数组中每个元素大小都为1字节
printf("%d\n", sizeof(arr[1]));//1
5.&arr表示整个数组地址,只要是地址大小就是4/8
printf("%d\n", sizeof(&arr));//4/8
6.&arr+1跳过的是整个数组,得到该数组后面的地址。只要是地址大小就是4/8
printf("%d\n", sizeof(&arr+1));//4/8
7.&arr[0]表示首元素地址,+1后跳过一个元素,得到第二个元素地址。只要是地址大小就是4/8
printf("%d\n", sizeof(&arr[0]+1));
回顾strlen函数:
①参数类型为字符指针类型char ∗ * ∗ ,参数不是指针类型的话会报错
②strlen函数计算的是字符指针指向的字符串的大小
③字符串以\0结尾
④strlen函数计算字符串时找\0,找不到的话就一直往后找,一直计数
⑤抛开字符串,其实计算的就是指针指向的位置与后面出现的第一个\0字符之间的字节数
创建一个由多个独立字符组成的字符数组
char arr[] = {'a','b','c','d','e','f'};
1.arr是数组首元素地址,strlen计算该地址到往后找到的第一个\0之间的字节数,arr里没有字符\0,因此得到的是随机值
printf("%d\n", strlen(arr));//随机值
2.arr是首元素地址,arr+0还是首元素地址,和1得到的结果一样
printf("%d\n", strlen(arr+0));//随机值
3. ∗ * ∗arr的是首元素,首元素是字符,不是指针,err
printf("%d\n", strlen(*arr));//err
4.arr[1]是第二个元素,是字符,不是指针,err
printf("%d\n", strlen(arr[1]);//err
5.&arr[0]是首元素地址,+1后是第二个元素地址,由于不知道哪里有\0,得到的是随机值
printf("%d\n", strlen(&arr[0]+1));//随机值
6.&arr是整个数组的地址,传过去的是数组指针,是char (*)[6]类型的,strlen函数需要接收的是首元素地址,即一个普通指针。虽然二者的指针类型不相同,但本质上都是指针,将&arr传入strlen函数后,strlen会将数组指针看做一个数组的首元素地址,从该指针指向的位置开始向后找\0,得到随机值
printf("%d\n", strlen(&arr));//随机值
7.&arr是整个数组的地址,+1后跳过了整个数组,得到的还是数组指针,strlen从该指针指向的位置开始向后找\0,得到随机值
printf("%d\n", strlen(&arr+1));//随机值
注:7和8中都算出来的是随机值,但8中的指针是从7向后跳过整个数组即6个字节得到的,因此7算出的随机值与8算出的随机值相差6
创造一个由一串字符串组成的字符数组,字符串“abcdef”等价于’a’,‘b’,‘c’,‘d’,‘e’,‘f’,'\0’这七个单个字符的组合,数组内实际存放了7个元素
char arr[] = "abcdef";
1.sizeof(arr)表示整个数组大小,7个char类型的元素,大小是7
printf("%d\n", sizeof(arr));//7
2.arr表示首元素地址,+0后还是首元素地址,地址均为4或8字节
printf("%d\n", sizeof(arr+0));//4/8
3.arr表示首元素地址, ∗ * ∗arr表示首元素,大小为1
printf("%d\n", sizeof(*arr));//1
4.arr[1]表示第二个元素,大小为1
printf("%d\n", sizeof(arr[1]));//1
5.&arr表示整个数组地址,地址均为4或8字节
printf("%d\n", sizeof(&arr));//4/8
6.&arr表示整个数组地址,+1后跳过整个数组,来到该数组后面的那个位置,本质是地址,4或8字节
printf("%d\n", sizeof(&arr+1));//4/8
7.&arr[0]是首元素地址,+1后跳过一个元素,指向第二个元素,指针均为4或8字节
printf("%d\n", sizeof(&arr[0]+1));//4/8
创造一个由一串字符串组成的字符数组,字符串“abcdef”等价于’a’,‘b’,‘c’,‘d’,‘e’,‘f’,'\0’这七个单个字符的组合,数组内实际存放了7个元素
char arr[] = "abcdef";
1.arr是指向数组首元素,strlen见到\0停止,从首元素到\0之间有6个字节
printf("%d\n", strlen(arr));//6
2.arr+0是数组首元素地址,和1等价,计算结果为6
printf("%d\n", strlen(arr+0));//7
3. ∗ * ∗arr是数组首元素,不是指针类型,err
printf("%d\n", strlen(*arr));//err
4.arr[1]是数组中第二个元素,不是指针类型,err
printf("%d\n", strlen(arr[1]));//err
5.&arr是整个数组地址,虽然是数组指针,但本质上还是指针,被strlen接收后从该指针位置开始寻找\0并计算,计算结果为6
printf("%d\n", strlen(&arr));//6
6.&arr+1表示跳过整个arr数组后所指向的位置,是指针,但是不知道后面\0放在哪,计算出随机值
printf("%d\n", strlen(&arr+1));//随机值
7.&arr[0]是首元素地址,+1后得到第二个元素地址,计算从第二个元素到\0之间的字节数5
printf("%d\n", strlen(&arr[0]+1));//5
创建一个指针变量p,指向字符串"acdef"的首元素(存放字符串首元素地址),字符串“abcdef”存放在某一特殊区域
char *p = "abcdef";
1.p是指针,指针均为4或8字节
printf("%d\n", sizeof(p));//4/8
2.p是字符型指针,+1后跳过一个char的字节数,即1,指向字符串第二个元素,但本质上还是指针,4或8字节
printf("%d\n", sizeof(p+1));//4/8
3. ∗ * ∗p是首元素,首元素是一个字符,大小为1
printf("%d\n", sizeof(*p));//1
4.p[0]是寿元是,大小为1
printf("%d\n", sizeof(p[0]));//1
5.p本身就是指针,&指针得到二级指针,但不管几级指针都是4或8字节
printf("%d\n", sizeof(&p));//4/8
6.在二级指针&p的基础上对指针移动,移动的大小是该指针指向的对象的类型大小,此处移动的大小是一个一级指针的大小,就相当于指针从p前移动到了p后
printf("%d\n", sizeof(&p+1));
7.p是指针,指向字符串“abcdef”是首元素,可以理解为字符串“abcdef”被存放在名叫p的字符数组中,则p[0]是首元素,&p[0]是首元素地址,&p[0]+1是第二个元素地址。地址均为4或8字节
printf("%d\n", sizeof(&p[0]+1));//4/8
创建一个指针变量,指向字符串的首元素(存放字符串首元素地址),字符串“abcdef”相当于’a’,‘b’,‘c’,‘d,’‘e’,‘f’,‘\0’
char *p = "abcdef";
1.从p指向的位置开始,向后找\0位置,二者间相隔6字节
printf("%d\n", strlen(p));//6
2.从p+1指向的位置开始,向后找\0位置,二者间相隔5字节
printf("%d\n", strlen(p+1));//5
3. ∗ * ∗p是字符串首元素,不是指针,err
printf("%d\n", strlen(*p));//err
4.p[0]是字符串首元素,不是指针,err
printf("%d\n", strlen(p[0]));//err
5.&p是二级指针,不知道该指针后面哪里有\0,随机值
printf("%d\n", strlen(&p));//随机值
6.&p+1是二级指针,相较于&p移动了一个一级指针的大小即4或8字节,不知道该指针后面哪里有\0,随机值
printf("%d\n", strlen(&p+1));//随机值
注:strlen(&p)和strlen(&p+1)的值没有关系。&p和&p+1两个指针之间相隔一个类型的大小即4字节,但strlen(&p)和strlen(&p+1)相差多少是不确定的,万一指针&p和&p+1之间的四个字节中就有\0呢,因此strlen(&p)和strlen(&p+1)二者的值无关联
7.&p[0]是首元素地址,+1后是第二个元素地址,该位置与后面的\0间相隔5字节
printf("%d\n", strlen(&p[0]+1));//5
创建一个二维数组,该二维数组由三个一维数组组成,每个一维数组内有四个元素
int a[3][4] = {0};
1.sizeof(a)计算整个数组大小,3乘4乘4=48
printf("%d\n",sizeof(a));//48
2.a[0][0]是二维数组第一行第一个元素,大小为4
printf("%d\n",sizeof(a[0][0]));//4
3.a[0]是二维数组第一行一整行的地址,是数组名地址,sizeof(a[0])计算的是第一行的大小,4*4=16
printf("%d\n",sizeof(a[0]));//16
4.a[0]是第一行数组名,没有单独放在sizeof内,没有与&结合,这里表示第一行第一个元素的地址,a[0]+1跳过一个元素,指向第一行第二个元素,地址均为4或8字节
printf("%d\n",sizeof(a[0]+1));//4/8
5.a[0]+1是第一行第二个元素地址, ∗ * ∗(a[0]+1)得到第一行第二个元素,大小为4
printf("%d\n",sizeof(*(a[0]+1)));//4
6.a没有单独放在sizeof内部,也没有与&结合,a是首元素即第一行地址,a+1就是第二行地址,地址均为4或8字节
printf("%d\n",sizeof(a+1));//4/8
分析法1: ∗ * ∗(a+1)⇔a[1],sizeof( ∗ * ∗(a+1))⇔sizeof(a[1]),计算的是第二行的大小
分析法2:a是第一行的地址,是数组指针int ( ∗ * ∗)[4]类型,a+1跳过的字节数就是int ( ∗ * ∗)[4]的大小,16
printf("%d\n",sizeof(*(a+1)));//16
8.&a[0]是第一行地址,数组指针类型,int( ∗ * ∗)[4],+1后跳过第一行,&a[0]+1是第二行地址,4或8
printf("%d\n",sizeof(&a[0]+1));//4/8
9.解引用第二行地址得到第二行一整行,16
printf("%d\n",sizeof(*(&a[0]+1)));//16
10.a没有单独放在sizeof内,也没有和&结合,a表示第一行地址,sizeof( ∗ * ∗a)计算的是第一行大小,16
printf("%d\n",sizeof(*a));//16
11.虽然arr[3]不在指针合法访问范围内,但sizeof不会真正去访问,只是计算该位置的空间大小而已。空间大小就是一整行大小,16
printf("%d\n",sizeof(a[3]));//16