关于 sizeof 和 strlen 的各种情况

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main()
{
 int a[] = { 1,2,3,4 };
 printf("%d\n", sizeof(a));//16
 printf("%d\n", sizeof(a + 0));//4,a已经隐式转换为指针int*
 printf("%d\n", sizeof(*a)); //4,a已经隐式转换为int*再解引用得到int
 printf("%d\n", sizeof(a+1));//4,a已经隐式转换为指针int*再+1还是int*
 printf("%d\n", sizeof(a[1]));//4,a[1]= *(a+1)还是指针int*
 printf("%d\n", sizeof(&a));//4,&a是一个数组指针int(*)[4]
 printf("%d\n", sizeof(*&a));//16,&a是数组指针,再次解引用从这个地址开始取int(*)[4]类型对应的的字节
 printf("%d\n", sizeof(&a+1));//4,数组指针+1还是指针
 printf("%d\n", sizeof(&a[0]));//4,得到int*
 printf("%d\n", sizeof(&a[0]+1));//4,指针+1还是int*
 return 0;
}

int main()
{
 char arr[] = { 'a','b','c','d','e','f' };
 printf("%d\n", sizeof(arr));//6,arr是字符数组
 printf("%d\n", sizeof(arr+0));//4,得到一个char*
 printf("%d\n", sizeof(*arr));//1,得到一个char
 printf("%d\n", sizeof(arr[1]));//1,得到一个char
 printf("%d\n", sizeof(&arr));//4,得到一个数组指针char(*)[6]
 printf("%d\n", sizeof(&arr+1));//4,数组指针+1还是指针
 printf("%d\n", sizeof(&arr[0]+1));//4,&arr[0]得到一个char*,+1还是指针
 
 printf("%d\n", strlen(arr));//针对一个不是字符串的字符数组进行strlen操作,未定义行为
 printf("%d\n", strlen(arr+0));
 printf("%d\n", strlen(*arr));//*arr得到的是'a'=>97,strlen就把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));
 return 0;
}

int main()
{
 char arr[] = "abcdef";
 printf("%d\n", sizeof(arr));//7,sizeof是求内存的大小,要包含\0
 printf("%d\n", sizeof(arr+0));//4,arr + 0 => char*
 printf("%d\n", sizeof(*arr));//1,*arr => char
 printf("%d\n", sizeof(arr[1]));//1,arr[1] = * (arr + 1) => char
 printf("%d\n", sizeof(&arr));//4,&arr=>char(*)[7]
 printf("%d\n", sizeof(&arr+1));//4,指针+1还是指针
 printf("%d\n", sizeof(&arr[0]+1));//4,&arr[0] => char*, + 1还是char*

 printf("%d\n", strlen(arr));//6,计算字符串长度。不算\0
 printf("%d\n", strlen(arr+0));//6
 printf("%d\n", strlen(*arr));//ub,*arr得到char,char和char*类型不匹配,按理说是要编译失败的
 printf("%d\n", strlen(arr[1]));//ub,理由同上
 printf("%d\n", strlen(&arr));//6,&arr=>char(*)[7],和char*类型不匹配,按理说是要编译失败的
         //&arr碰巧和arr得到的地址值是相同的值。这个结果能算对,纯属巧合
 printf("%d\n", strlen(&arr+1));//ub,&arr+1跳过了整个数组,访问数组后面的空间,非法内存
 printf("%d\n", strlen(&arr[0]+1));//5,&arr[0] => char* , char* + 1跳过一个char
 return 0;
}

int main()
{
 char* p = "abcdef";
 printf("%d\n", sizeof(p));//4,p=>char*
 printf("%d\n", sizeof(p+1));//4,p+1还是char*
 printf("%d\n", sizeof(*p));//1,*p=char
 printf("%d\n", sizeof(p[0]));//1,p[0]=*(p+0)=>char
 printf("%d\n", sizeof(&p));//4,p=>char*,&p=>char**
 printf("%d\n", sizeof(&p+1));//4,&p + 1还是char**
 printf("%d\n", sizeof(&p[0]+1));//4,&p[0]=>char*,+1还是char*

 printf("%d\n", strlen(p));//6
 printf("%d\n", strlen(p+1));//5,从p+1的位置往后找5个元素得到\0;
 printf("%d\n", strlen(*p));//ub,*p=>char,和char*类型不匹配
 printf("%d\n", strlen(p[0]));//ub,同上
 printf("%d\n", strlen(&p));//ub,&p=>char**
 printf("%d\n", strlen(&p+1));//ub
 printf("%d\n", strlen(&p[0]+1));//5,&p[0]=>p+1
 return 0;
}

int main()
{
 int a[3][4] = { 0 };//所谓二维数组,本质是一个一维数组,里面的每个元素又是一个一维数组
 printf("%d\n", sizeof(a));//48,12个元素,每个元素4个字节
 printf("%d\n", sizeof(a[0][0]));//4
 printf("%d\n", sizeof(a[0]));//16,a[0]=>int[4]
 printf("%d\n", sizeof(a[0]+1));//4,a[0]=>int[4]再+1,就隐式转换成指针int*
 printf("%d\n", sizeof(*(a[0]+1)));//4,int*解引用得到int,*(a[0]+1)=>a[0][1]
 printf("%d\n", sizeof(&a[0]+1));//4,a[0]=int[4],&a[0]=>int(*)[4],再+1还是指针
 printf("%d\n", sizeof(*(&a[0]+1)));//16,上面解引用得到int[4]
 printf("%d\n", sizeof(*a));//16,*a=>*(a+0)=>a[0],得到int[4]
 printf("%d\n", sizeof(a[3]));//16,sizeof是一个运算符,特点是编译期求值
                              //“数组下标越界未定义行为”前提条件是内存访问越界,这是程序运行时的行为
 return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值