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

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

🎈一.sizeof与int a[ ]
👻创建一个整型数组

int a[] = {1,2,3,4};
1
1.sizeof(数组名)表整个数组的大小。4*4=16

printf(“%d\n”,sizeof(a));//4*4=16
1
2.a表示首元素地址,a+0还是首元素地址。地址大小为4或8字节

printf(“%d\n”,sizeof(a+0));//4/8
1
3.*a表示首元素,整型一维数组中每个元素都是4字节

printf(“%d\n”,sizeof(*a));//4
1
4.a+1表示跳过首元素,指向第二个元素地址。地址大小为4或8字节

printf(“%d\n”,sizeof(a+1));//4/8
1
5.a[1]表示第二个元素,整型一维数组中每个元素都是4字节

printf(“%d\n”,sizeof(a[1]));//4
1
6.&a是整个数组的地址,地址大小为4或8字节

printf(“%d\n”,sizeof(&a));//4/8
1
7.sizeof(∗ ∗&a)–>sizeof(a)–>整个数组大小,44=16
🌟∗ *∗和&互为逆运算,会抵消

printf(“%d\n”,sizeof(*&a));//16
1
8.&a表示整个数组地址,&a+1跳过的是整个数组,得到的是地址,地址大小为4或8字节

printf(“%d\n”,sizeof(&a+1));//4/8
1
9.&a[0]表示首元素地址,地址大小为4或8字节

printf(“%d\n”,sizeof(&a[0]));//4/8
1
10.&a[0]+1表示跳过首元素,得到第二个元素地址,地址大小为4或8字节

printf(“%d\n”,sizeof(&a[0]+1));//4/8
1
🎈二.sizeof与char arr[ ](由多个独立字符组成的字符数组)
👻创建一个由多个独立字符组成的字符数组

char arr[] = {‘a’,‘b’,‘c’,‘d’,‘e’,‘f’};
1
1.sizeof(arr)计算整个数组大小,1*6=6

printf(“%d\n”, sizeof(arr));//6
1
2.arr表示首元素地址,arr+0还是首元素地址,4/8

printf(“%d\n”, sizeof(arr+0));//4/8
1
3.∗ *∗arr表示首元素,字符型一维数组中每个元素大小都为1字节

printf(“%d\n”, sizeof(*arr));//1
1
4.arr[1]表示数组中第二个元素,字符型一维数组中每个元素大小都为1字节

printf(“%d\n”, sizeof(arr[1]));//1
1
5.&arr表示整个数组地址,只要是地址大小就是4/8

printf(“%d\n”, sizeof(&arr));//4/8
1
6.&arr+1跳过的是整个数组,得到该数组后面的地址。只要是地址大小就是4/8

printf(“%d\n”, sizeof(&arr+1));//4/8
1
7.&arr[0]表示首元素地址,+1后跳过一个元素,得到第二个元素地址。只要是地址大小就是4/8

printf(“%d\n”, sizeof(&arr[0]+1));
1
🎈三.strlen与char arr[ ](由多个独立字符组成的字符数组)
🌟回顾strlen函数:
①参数类型为字符指针类型char∗ *∗ ,参数不是指针类型的话会报错
②strlen函数计算的是字符指针指向的字符串的大小
③字符串以\0结尾
④strlen函数计算字符串时找\0,找不到的话就一直往后找,一直计数
⑤抛开字符串,其实计算的就是指针指向的位置与后面出现的第一个\0字符之间的字节数

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

char arr[] = {‘a’,‘b’,‘c’,‘d’,‘e’,‘f’};
1
1.arr是数组首元素地址,strlen计算该地址到往后找到的第一个\0之间的字节数,arr里没有字符\0,因此得到的是随机值

printf(“%d\n”, strlen(arr));//随机值
1
2.arr是首元素地址,arr+0还是首元素地址,和1得到的结果一样

printf(“%d\n”, strlen(arr+0));//随机值
1
3.∗ *∗arr的是首元素,首元素是字符,不是指针,err

printf(“%d\n”, strlen(*arr));//err
1
4.arr[1]是第二个元素,是字符,不是指针,err

printf(“%d\n”, strlen(arr[1]);//err
1
5.&arr[0]是首元素地址,+1后是第二个元素地址,由于不知道哪里有\0,得到的是随机值

printf(“%d\n”, strlen(&arr[0]+1));//随机值
1
6.&arr是整个数组的地址,传过去的是数组指针,是char (*)[6]类型的,strlen函数需要接收的是首元素地址,即一个普通指针。虽然二者的指针类型不相同,但本质上都是指针,将&arr传入strlen函数后,strlen会将数组指针看做一个数组的首元素地址,从该指针指向的位置开始向后找\0,得到随机值

printf(“%d\n”, strlen(&arr));//随机值
1
7.&arr是整个数组的地址,+1后跳过了整个数组,得到的还是数组指针,strlen从该指针指向的位置开始向后找\0,得到随机值

printf(“%d\n”, strlen(&arr+1));//随机值
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
1.sizeof(arr)表示整个数组大小,7个char类型的元素,大小是7

printf(“%d\n”, sizeof(arr));//7
1
2.arr表示首元素地址,+0后还是首元素地址,地址均为4或8字节

printf(“%d\n”, sizeof(arr+0));//4/8
1
3.arr表示首元素地址,∗ *∗arr表示首元素,大小为1

printf(“%d\n”, sizeof(*arr));//1
1
4.arr[1]表示第二个元素,大小为1

printf(“%d\n”, sizeof(arr[1]));//1
1
5.&arr表示整个数组地址,地址均为4或8字节

printf(“%d\n”, sizeof(&arr));//4/8
1
6.&arr表示整个数组地址,+1后跳过整个数组,来到该数组后面的那个位置,本质是地址,4或8字节

printf(“%d\n”, sizeof(&arr+1));//4/8
1
7.&arr[0]是首元素地址,+1后跳过一个元素,指向第二个元素,指针均为4或8字节

printf(“%d\n”, sizeof(&arr[0]+1));//4/8
1
🎈五.strlen与char arr[ ](以字符串形式初始化数组)
👻创造一个由一串字符串组成的字符数组,字符串“abcdef”等价于’a’,‘b’,‘c’,‘d’,‘e’,‘f’,'\0’这七个单个字符的组合,数组内实际存放了7个元素

char arr[] = “abcdef”;
1
1.arr是指向数组首元素,strlen见到\0停止,从首元素到\0之间有6个字节

printf(“%d\n”, strlen(arr));//6
1
2.arr+0是数组首元素地址,和1等价,计算结果为6

printf(“%d\n”, strlen(arr+0));//7
1
3.∗ *∗arr是数组首元素,不是指针类型,err

printf(“%d\n”, strlen(*arr));//err
1
4.arr[1]是数组中第二个元素,不是指针类型,err

printf(“%d\n”, strlen(arr[1]));//err
1
5.&arr是整个数组地址,虽然是数组指针,但本质上还是指针,被strlen接收后从该指针位置开始寻找\0并计算,计算结果为6

printf(“%d\n”, strlen(&arr));//6
1
6.&arr+1表示跳过整个arr数组后所指向的位置,是指针,但是不知道后面\0放在哪,计算出随机值

printf(“%d\n”, strlen(&arr+1));//随机值
1
7.&arr[0]是首元素地址,+1后得到第二个元素地址,计算从第二个元素到\0之间的字节数5

printf(“%d\n”, strlen(&arr[0]+1));//5
1
🎈六.sizeof与字符串首元素地址
👻创建一个指针变量p,指向字符串"acdef"的首元素(存放字符串首元素地址),字符串“abcdef”存放在某一特殊区域

char *p = “abcdef”;
1
1.p是指针,指针均为4或8字节

printf(“%d\n”, sizeof§);//4/8
1
2.p是字符型指针,+1后跳过一个char的字节数,即1,指向字符串第二个元素,但本质上还是指针,4或8字节

printf(“%d\n”, sizeof(p+1));//4/8
1
3.∗ *∗p是首元素,首元素是一个字符,大小为1

printf(“%d\n”, sizeof(*p));//1
1
4.p[0]是寿元是,大小为1

printf(“%d\n”, sizeof(p[0]));//1
1
☀️难点:sizeof(&p)
5.p本身就是指针,&指针得到二级指针,但不管几级指针都是4或8字节

printf(“%d\n”, sizeof(&p));//4/8
1
☀️难点:sizeof(&p+1)
6.在二级指针&p的基础上对指针移动,移动的大小是该指针指向的对象的类型大小,此处移动的大小是一个一级指针的大小,就相当于指针从p前移动到了p后

printf(“%d\n”, sizeof(&p+1));
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
1
🎈七.strlen与字符串首元素地址
👻创建一个指针变量,指向字符串的首元素(存放字符串首元素地址),字符串“abcdef”相当于’a’,‘b’,‘c’,‘d,’‘e’,‘f’,‘\0’

char *p = “abcdef”;
1
1.从p指向的位置开始,向后找\0位置,二者间相隔6字节

printf(“%d\n”, strlen§);//6
1
2.从p+1指向的位置开始,向后找\0位置,二者间相隔5字节

printf(“%d\n”, strlen(p+1));//5
1
3.∗ *∗p是字符串首元素,不是指针,err

printf(“%d\n”, strlen(*p));//err
1
4.p[0]是字符串首元素,不是指针,err

printf(“%d\n”, strlen(p[0]));//err
1
5.&p是二级指针,不知道该指针后面哪里有\0,随机值

printf(“%d\n”, strlen(&p));//随机值
1
6.&p+1是二级指针,相较于&p移动了一个一级指针的大小即4或8字节,不知道该指针后面哪里有\0,随机值

printf(“%d\n”, strlen(&p+1));//随机值
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
1
🎈八.sizeof与二维数组
☀️回顾二维数组:
二维数组的每个元素都是一维数组

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

int a[3][4] = {0};
1
1.sizeof(a)计算整个数组大小,3乘4乘4=48

printf(“%d\n”,sizeof(a));//48
1
2.a[0][0]是二维数组第一行第一个元素,大小为4

printf(“%d\n”,sizeof(a[0][0]));//4
1
3.a[0]是二维数组第一行一整行的地址,是数组名地址,sizeof(a[0])计算的是第一行的大小,4*4=16

printf(“%d\n”,sizeof(a[0]));//16
1
4.a[0]是第一行数组名,没有单独放在sizeof内,没有与&结合,这里表示第一行第一个元素的地址,a[0]+1跳过一个元素,指向第一行第二个元素,地址均为4或8字节

printf(“%d\n”,sizeof(a[0]+1));//4/8
1
5.a[0]+1是第一行第二个元素地址,∗ *∗(a[0]+1)得到第一行第二个元素,大小为4

printf(“%d\n”,sizeof(*(a[0]+1)));//4
1
6.a没有单独放在sizeof内部,也没有与&结合,a是首元素即第一行地址,a+1就是第二行地址,地址均为4或8字节

printf(“%d\n”,sizeof(a+1));//4/8
1
分析法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
1
8.&a[0]是第一行地址,数组指针类型,int(∗ *∗)[4],+1后跳过第一行,&a[0]+1是第二行地址,4或8

printf(“%d\n”,sizeof(&a[0]+1));//4/8
1
9.解引用第二行地址得到第二行一整行,16

printf(“%d\n”,sizeof(*(&a[0]+1)));//16
1
10.a没有单独放在sizeof内,也没有和&结合,a表示第一行地址,sizeof(∗ *∗a)计算的是第一行大小,16

printf(“%d\n”,sizeof(*a));//16
1
11.虽然arr[3]不在指针合法访问范围内,但sizeof不会真正去访问,只是计算该位置的空间大小而已。空间大小就是一整行大小,16

printf(“%d\n”,sizeof(a[3]));//16

  • 15
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值