C语言sizeof和strlen使用时遇到的“坑”

**sizeof:**返回一个对象或者类型所占的内存字节数
**strlen:**返回字符串的长度

一.sizeof

1)*数组名大多数情况下指的是数组的首元素地址,但在sizeof(数组名)表示的却是整个数组

数组名只有在 sizeof(数组名)&数组名 的情况下表示整个数组,其他所有情况表示首元素地址。

int main()
{
//数组名是首元素地址
//1.sizeof(数组名)- 数组名表示整个数组

int a[] = {1, 2, 3, 4};
printf("%d\n",sizeof(a));//计算的数组的总大小-单位是字节-16
printf("%d\n",sizeof(a+0));//这里的a表示首元素地址,a+0还是首元素地址,所以大小是4或8个字节(32位操作系统4;64位操作系统8)
printf("%d\n",sizeof(*a));//数组名表示首元素地址,*a就是首元素,所以大小是4个字节
printf("%d\n",sizeof(a+1));//这里a表示的还是首元素地址,a+1就是第二个元素的地址,地址大小就是4或8个字节
printf("%d\n",sizeof(a[1]));//第二个元素的大小 4个字节
printf("%d\n",sizeof(&a));//&a是数组的地址,数组的地址也是地址,所以大小仍是4或8个字节
printf("%d\n",sizeof(*&a));//&a数组的地址,数组的地址解引用 访问的是数组,所以是数组的大小16字节
printf("%d\n",sizeof(&a+1));//这里还是4字节,后面我画图解释
printf("%d\n",sizeof(&a[0]));//a[0]指的是首元素,&a[0]就是首元素地址,所以这里仍然是4或8个字节
printf("%d\n",sizeof(&a[0]+1));//&a[0]是首元素地址,&a[0]+1就是第二个元素的地址
return 0;
}

在这里插入图片描述
sizeof(&a+1),&a是数组的地址,&a+1,跳过了一个数组,但还是地址,所以还是4/8个字节

int main()
{
char arr[] = {'a', 'b', 'c', 'd', 'e', 'f'};
printf("%d\n",sizeof(arr));//sizeof计算的是数组的大小,字符数组一般末尾还有一个/0,所以是6个字节
printf("%d\n",sizeof(arr + 0));//arr是首元素地址,arr+0还是首元素地址,所以大小4/8个字节
printf("%d\n",sizeof(*arr));//arr是首元素的地址,*arr是首元素,首元素是字符,所以是1字节
printf("%d\n",sizeof(arr[1])); //1字节
printf("%d\n",sizeof(&arr));//&arr虽然是数组的地址,但还是地址,地址大小是4/8个字节
printf("%d\n",sizeof(&arr+1));// 跳过这个数组后的一个地址,大小仍然是4/8个字节
printf("%d\n",sizeof(&arr[0]+1));//第二个元素地址 4/8个字节
return 0;
}
char arr[] = {'a','b','c','d','e','f'};
printf("%d\n",sizeof(arr));//6
printf("%d\n",sizeof(arr + 0));//4或8
printf("%d\n",sizeof(*arr));//1
printf("%d\n",sizeof(arr[1]));//1

printf("%d\n",sizeof(&arr));//4或8
printf("%d\n",sizeof(&arr + 1));//4或8
printf("%d\n",sizeof(&arr[0] + 1));//4或8
char *p= "abcdef";

printf("%d\n",sizeof(p));//4或8  计算指针变量p的大小
printf("%d\n",sizeof(p + 1));//4或8  字符串第二个字符b
printf("%d\n",sizeof(*p));//1  字符串第一个字符a
printf("%d\n",sizeof(p[1]));//1  int arr[10];arr[0]==*(arr + 0);p[0]==*(p+0)=='a'
printf("%d\n",sizeof(&arr));//4或8  地址
printf("%d\n",sizeof(&arr + 1));//4或8  地址
printf("%d\n",sizeof(&arr[0] + 1));//4或8  地址

二、strlen

char arr[] = {'a','b','c','d','e','f'};
printf("%d\n",strlen(arr));//随机值,因为arr是首地址,strlen遇到0停下,所以不知道会返回多少
printf("%d\n",strlen(arr + 0));//随机值
printf("%d\n",strlen(*arr));//error
printf("%d\n",strlen(arr[1]));//error

printf("%d\n",strlen(&arr));//随机值
printf("%d\n",strlen(&arr + 1));//随机值-6
printf("%d\n",strlen(&arr[0] + 1));//随机值-1

再看下一个

char arr[] = "abcdef";

printf("%d\n",strlen(arr));//6
printf("%d\n",strlen(arr + 0));//6
printf("%d\n",strlen(*arr));//error
printf("%d\n",strlen(arr[1]));//error

printf("%d\n",strlen(&arr));//6  &arr - 数组的地址-数组的指针char(*p)[7]=&arr;
printf("%d\n",strlen(&arr + 1));//随机值printf("%d\n",strlen(&arr[0] + 1));//5

再来一个

char *p = "abcdef";

printf("%d\n",strlen(p));//6
printf("%d\n",strlen(arr + 0));//6
printf("%d\n",strlen(*p));//error
printf("%d\n",strlen(p[0]));//error

printf("%d\n",strlen(&p));//随机值
printf("%d\n",strlen(&p + 1));//随机值printf("%d\n",strlen(p + 1));//5

三、二维数组

int a[3][4] = {0};
printf("%p\n",&a[0][0]);
printf("%p\n",a[0] + 1);
printf("%p\n",a + 1);
printf("%p\n",&a[0] + 1);

printf("%d\n",sizeof(a));//48
printf("%d\n",sizeof(a[0][0]));//4
printf("%d\n",sizeof(a[0]));//16 a[0]相当于第一行,相当于第一行 一维数组的数组名
//sizeof(arr[0])把数组名单独放在sizeof()内,计算的第一行的大小 
printf("%d\n",sizeof(a[0] + 1));//4 - a[0]是第一行的数组名,数组名此时是首元素的地址,a[0]其实就是第一行第一个元素的地址
printf("%d\n",sizeof(*(a[0] + 1)));//4 *(a[0] + 1)是第一行第二个元素,大小是4个字节
printf("%d\n",sizeof(a+1));//4 //a是二位数组的数组名,没有sizeof(a),也没有&(a),所以a是首元素地址
//而二维数组看成一维数组时,二维数组的首元素是他的第一行,a就是第一行(首元素)的地址
//a + 1就是第二行的地址 

printf("%d\n",sizeof(*(a + 1)));//16 sizeof(a[1])计算第二行的大小,单位是字节
printf("%d\n",sizeof(&a[0] + 1));//4 第二行的地址
printf("%d\n",sizeof(*(&a[0] + 1)));//16 计算的是第二行的大小,单位是字节
printf("%d\n", sizeof(*a));//16   a是首元素地址,第一行的地址, *a就是第一行,所以是第一行的大小
printf("%d\n", sizeof(a[3]));//16
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值