用sizeof和strlen计算数组或指针大小

数组名的意义

用sizeof和strlen计算数组或指针大小_第1张图片

一.sizeof与int a[ ]

创建一个整型数组

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

二.sizeof与char arr[ ](由多个独立字符组成的字符数组)

创建一个由多个独立字符组成的字符数组

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 arr[ ](由多个独立字符组成的字符数组)

回顾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

四.sizeof与char arr[ ](以字符串形式初始化数组)

创造一个由一串字符串组成的字符数组,字符串“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

五.strlen与char arr[ ](以字符串形式初始化数组)

创造一个由一串字符串组成的字符数组,字符串“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

六.sizeof与字符串首元素地址

创建一个指针变量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

☀️难点:sizeof(&p)

5.p本身就是指针,&指针得到二级指针,但不管几级指针都是4或8字节

printf("%d\n", sizeof(&p));//4/8

☀️难点:sizeof(&p+1)

6.在二级指针&p的基础上对指针移动,移动的大小是该指针指向的对象的类型大小,此处移动的大小是一个一级指针的大小,就相当于指针从p前移动到了p后
用sizeof和strlen计算数组或指针大小_第2张图片

printf("%d\n", sizeof(&p+1));

☀️难点:&p[0]+1

7.p是指针,指向字符串“abcdef”是首元素,可以理解为字符串“abcdef”被存放在名叫p的字符数组中,则p[0]是首元素,&p[0]是首元素地址,&p[0]+1是第二个元素地址。地址均为4或8字节

printf("%d\n", sizeof(&p[0]+1));//4/8

七.strlen与字符串首元素地址

创建一个指针变量,指向字符串的首元素(存放字符串首元素地址),字符串“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

八.sizeof与二维数组

☀️回顾二维数组:
二维数组的每个元素都是一维数组
用sizeof和strlen计算数组或指针大小_第3张图片

创建一个二维数组,该二维数组由三个一维数组组成,每个一维数组内有四个元素

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

你可能感兴趣的:(c语言)