C语言基础:数组在内存存储的大小(sizeof,strlen求大小)

整形数组: 

int main()
{
	//数组名首元素地址,下面是两个例外
	//1.sizeof(数组名)-数组名表示整个数组
	//2.&数组名-数组名表示整个数组
	
	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));//计算的是数组总大小,单位是字节-16
	printf("%d\n", sizeof(a+0));//此时的a还是首元素地址 32平台4个字节,64平台为8
	printf("%d\n", sizeof(*a));//求的是首元素的大小,4个字节
	printf("%d\n", sizeof(a+1));//4/8
	printf("%d\n", sizeof(a[1]));//4
	printf("%d\n", sizeof(&a));//不是16,&a取出的是数组的地址,但是数组的地址那也是地址,地址的大小就是4/8个字节
	printf("%d\n", sizeof(*&a));//16 与第一种写法一样
	printf("%d\n", sizeof(&a+1));//4/8,虽然跳过整个数组,但是还是地址,
	printf("%d\n", sizeof(&a[0]));//4/8
}

字符数组:

char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));//6 sizeof计算的是数组大小
	printf("%d\n", sizeof(arr+0));//4/8 首元素地址
	printf("%d\n", sizeof(*arr));//1  *arr就是首元素,大小一个字节
	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 第二个元素的地址

32为平台运行结果: 

 strlen 求字符串长度的函数,遇到\0结束

char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", strlen(arr));//随机值  没有结束标志\0
	printf("%d\n", strlen(arr+0));//与第一种写法相同,还是随机值
	printf("%d\n", strlen(*arr));//‘a'-97 把97 当做地址,非法访问内存,
	printf("%d\n", strlen(arr[1]));//非法访问
	printf("%d\n", strlen(&arr));//随机
	printf("%d\n", strlen(&arr+1));//随机
	printf("%d\n", strlen(&arr[0] + 1));//随机
char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));//7   计算的是整个数组大小,单位是字节
	printf("%d\n", sizeof(arr+0));//4/8  算的是首元素地址的大小
	printf("%d\n", sizeof(*arr));//*arr是首元素,首元素大小是1个字节
	printf("%d\n", sizeof(arr[1]));//1
	printf("%d\n", sizeof(&arr));//4/8 算的是地址的大小  &arr虽然是数组的地址,但是也是地址
	printf("%d\n", sizeof(&arr+1));//4/8  &arr+1是跳过整个数组后的地址,还是地址
	printf("%d\n", sizeof(&arr [0]+ 1));//4/8
}
 char arr[] = "abcdef";
	   printf("%d\n", strlen(arr));//6  不包括\0     strlen接收的是地址,从那个地址开始找字符串
	   printf("%d\n", strlen(arr+0));//6
	   printf("%d\n", strlen(*arr));//非法访问内存   97 当做地址去访问
	   printf("%d\n", strlen(arr[1]));//非法访问内存  98 当做地址去访问
	   printf("%d\n", strlen(&arr));//6   会有警告
	   printf("%d\n", strlen(&arr+1));//随机值
	   printf("%d\n", strlen(&arr[0]+1));//5

 printf("%d\n", strlen(&arr));

会报错,  &arr-数组的地址,按理说存在数组指针里面 char(*p)[7]=&arr; 元素类型为char(*)[7];

而strlen接收的类型是 const char *,有所冲突 

下面解释一下如下代码:

char* p = "abcdef";
	//常量字符串,把a的地址放到p指针
	printf("%d\n", sizeof(p));//4/8 a的地址  
	printf("%d\n", sizeof(p+1));//4/8 b的地址 
	printf("%d\n", sizeof(*p));//1 a的大小
	printf("%d\n", sizeof(p[0]));//int arr[10]; arr[0]==*(arr+0)  p[0]==*(p+0)  1
	printf("%d\n", sizeof(&p));//4/8 p的地址还是4个字节
	printf("%d\n", sizeof(&p+1));//4/8 还是个地址
	printf("%d\n", sizeof(&p[0]+1));//b的地址 还是4/8
char* p = "abcdef";
	printf("%d\n", strlen(p));//6
	printf("%d\n", strlen(p+1)); //5
	printf("%d\n", strlen(*p));//报错
	printf("%d\n", strlen(p[0]));//报错
	printf("%d\n", strlen(&p));//随机值
	printf("%d\n", strlen(&p+1));//随机值
	printf("%d\n", strlen(&p[0]+1));//5

 二维数组:

 printf("%d\n", sizeof(a[0]+1));

16 第二行的数组名,计算的是第二行的数组大小(错误) 

printf("%p\n", &a[0][0]);
printf("%p\n", &a[0]+1);

他们的值相差4

int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));//48 数组总大小,单位字节
	printf("%d\n", sizeof(a[0][0]));//4
	printf("%d\n", sizeof(a[0]));//16  第一行的数组名,计算的是第一行的数组大小
	printf("%d\n", sizeof(a[0]+1));//4  a[0]是第一行数组名,数组名此时是首元素地址,a[0]其实就是第一行第一个元素的地址
	//所以a[0]+1就是第一行第二个元素的地址 地址大小是4/8个字节     ????
	
	printf("%d\n", sizeof(*(a[0]+1)));//4 第一行第二个元素,大小是4个字节 
	printf("%d\n", sizeof(a+1));//a是二维数组的数组名,没有sizeof(a),也没有&a,所以a是首元素地址
	//而把二维数组看成一维数组时,二维数组首元素就是他的第一行,a就是第一行的地址   ???
	//a+1就是第二行的地址
	printf("%d\n", sizeof(*(a + 1)));//16  计算第二行的大小,单位是字节   ???
	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  ????

打???表示不太理解 

结果为:

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值