数组与指针与strlen和sizeof有关的试题解析

sizeof与strlen

二者的区别

sizeof
操作符,计算的是所占内存的大小,单位是字节,与内存中的数据无关

strlen
库函数,使用时需要包含头文件string.h,计算的是字符串的长度(统计的是\0之前的字符串长度),使用时关注内存中是否有"\0",没有的话,将会持续计算,导致越界
strlen

数组各形式所占内存大小

  1. 整型数组
//数组名除了两种情况外,均指首元素的地址
//特殊情况1:sizeof(数组名):计算整个数组的大小
//特殊情况2:&数组名:取出的是整个数组的地址
#include<stdio.h>
int main()
{
	int a[]={1,2,3,4}
	printf("%d\n",sizeof(a));//计算整个数组的大小:4*4=16个字节
	printf("%d\n",sizeof(a+0));//a没有单独地放在sizeof内部,也没有&,所以此时的a表示的是首元素的地址,+0后仍然是首元素的地址:4/8个字节
	//地址的内存大小都是4/8,取决于在64位还是84位
	printf("%d\n",sizeof(*a));//a是首元素的地址,//a=&a[1],*a就是第一个元素:4个字节
	printf("%d\n",sizeof(a+1));//a是首元素的地址,*p==a;*p+1-->指向下一个元素,因此(a+1)表示的&a[1](第二个元素的地址):4/8个字节
	printf("%d\n",sizeof(a[1]));//第二个元素的大小:4个字节
	printf("%d\n",sizeof(&a));//整个数组的地址的大小:4/8个字节
	printf("%d\n",sizeof(*&a));//*&可以相互抵消,看成sizeof(a):16个字节
	printf("%d\n",sizeof(&a+1));//跳过整个数组后的地址:4/8个字节
	printf("%d\n",sizeof(&a[0]));//第一个元素的地址:4/8个字节
	printf("%d\n",sizeof(&a[0]+1))//第二个元素的地址:4/8个字节
	return 0;
}``

  1. 字符数组
char arr[] = {'a','b','c','d','e','f')
printf("%d\n", sizeof(arr));//整个数组的大小:6个字节
printf("%d\n", sizeof(arr+0));//不是单独存在于sizeof内部,arr表示首元素的地址,+0同理:4/8个字节
printf("%d\n", sizeof(*arr));//arr表示首元素的地址,*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 arr[] = {'a','b','c','d','e','f'}
printf("%d\n", strlen(arr));//随机值,没有明确给出'\0'
printf("%d\n", strlen(arr+0));//arr+0->arr 同样是随机值
printf("%d\n", strlen(*arr));//*arr->'a'->97  非法访问 err
printf("%d\n", strlen(arr[1]));//arr[1]->'b'->98 非法访问 err
printf("%d\n", strlen(&arr));//随机值
printf("%d\n", strlen(&arr+1));//随机值
printf("%d\n", strlen(&arr[0]+1));//随机值
char arr[] = "abcdef";//a b c d e f \0
printf("%d\n", sizeof(arr));//整个数组的大小:7个字节
printf("%d\n", sizeof(arr+0));//arr为首元素地址,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 arr[] = "abcdef";
printf("%d\n", strlen(arr));//arr表示首元素地址,6个字节
printf("%d\n", strlen(arr+0));//arr仍表示首元素的地址,同上6个字节
printf("%d\n", strlen(*arr));//'a'->97 非法访问 err
printf("%d\n", strlen(arr[1]));//b ->98 非法访问 err
printf("%d\n", strlen(&arr));//6,&arr是数组的地址,指向数组的起始位置,strlen从起始位置向后计算直到'\0'
printf("%d\n", strlen(&arr+1));//跳过整个数组,随机值
printf("%d\n", strlen(&arr[0]+1));//以第二个元素为起始位置,长度为5
char *p = "abcdef";
printf("%d\n", sizeof(p));//p是指针变量,指针变量的大小为4/8个字节
printf("%d\n", sizeof(p+1));//p+1指向:'b'的地址,为4/8个字节
printf("%d\n", sizeof(*p));//*p=='a',1个字节
printf("%d\n", sizeof(p[0]));//首元素-1个字节
printf("%d\n", sizeof(&p));//&p是指针变量p的地址,为4/8个字节
printf("%d\n", sizeof(&p+1));//跳过变量p后的地址,还是地址,4/8个字节
printf("%d\n", sizeof(&p[0]+1));//第二个元素的地址,4/8个字节
char *p = "abcdef";//a b c d e f \0
printf("%d\n", strlen(p));//p中存放的是a的地址,从a向后访问,因此长度为6
printf("%d\n", strlen(p+1));//p+1是从'b'开始向后访问,长度为5个字节
printf("%d\n", strlen(*p));//*p->'a'->97 非法访问 err
printf("%d\n", strlen(p[0]));//非法访问
printf("%d\n", strlen(&p));//&p是p的地址,从p所占的空间的起始位置开始查找的,为随机值
printf("%d\n", strlen(&p+1));//跳过访问下一个地址,为随机值
printf("%d\n", strlen(&p[0]+1));//&p[0]+1->从第二个元素开始计算。长度为5
  1. 二维数组
    二维数组可以看成一维数组的数组,比如下面这组数组:a[3][4],可以画图来进行解释:

	int a[3][4] = { 0 };
    printf("%d\n", sizeof(a));//a是二维数组的数组名,计算的是整个二维数组的大小:3*4*4=48个字节
    printf("%d\n", sizeof(a[0][0]));//表示二维数组第一行的第一个元素,大小是4个字节
    printf("%d\n", sizeof(a[0]));//可以将a[0]当成第一行的数组名,计算的是第一行所有元素的大小:4*4=16个字节
    printf("%d\n", sizeof(a[0] + 1));//a[0]是第一行的数组名,且并非单独存在,因此,表示的是第一行首元素的地址,a[0]+1则表示第一行第二个元素的地址,大小为4/8个字节
    printf("%d\n", sizeof(*(a[0] + 1)));//第一行第二个元素的大小:4个字节
    printf("%d\n", sizeof(a + 1));//a不是单独存在函数内部,表示二维数组首元素的地址,也就是第一行的地址,因此a+1表示第二行的地址,大小为4/8个字节
    printf("%d\n", sizeof(*(a + 1)));//第二行元素的大小,为16个字节
    printf("%d\n", sizeof(&a[0] + 1));//&a[0]表示第一行的地址,a[0]+1表示第二行的地址,为4/8
    printf("%d\n", sizeof(*(&a[0] + 1)));//16个字节
    printf("%d\n", sizeof(*a));//a非单独存在,表示二维数组首元素的地址,也就是一行的地址,*a为第一行的元素,大小为16个字节
    printf("%d\n", sizeof(a[3]));//a[3]是数组名,表示第三行的元素,大小为16
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值