深入sizeof与strlen

文章详细比较了C语言中的sizeof和strlen函数,sizeof用于计算内存占用,对类型和内容无关,而strlen专用于计算字符串长度,不包括结束符。同时讨论了数组名、指针和不同类型的内存计算示例。
摘要由CSDN通过智能技术生成

一、sizeof与strlen的对比

sizeofstrlen
sizeof是单目操作符strlen是库函数,使用需要包含头文件string.h
sizeof计算操作数所占用的内存,单位是字节strlen是求字符串长度,统计的是\0之前字符的个数
不关注内存中存放什么数据

关注内存总是否有\0,如果没有就会持续

往后找,甚至越界

sizeof不挑类型指针针对字符串

strlen是指针且针对字符串,strlen 原型是size_t strlen(const char *str);

数组名:数组名一般表示数组首元素地址但有两个例外;

1.siziof(数组名):数组名表示整个数组,计算的是整个数组的大小,单位字节。

2.&数组名:数组名表示整个数组,取出的是整个数组的地址。

指针的大小:指针在x86环境下大小为4,在x64环境下为8,单位字节。

一维数组:

int main()
{
    int a[] = { 1, 2, 3, 4 };//arr数组中有四个元素每个元素都是int类型(占四个字节)
    printf("%zd\n", sizeof(a));//sizeof(a)取出的是整个数组的大小16
    printf("%zd\n", sizeof(a+0));//a+0中的a数组名表示数组首元素地址,地址即指针,指针大小4/8
    printf("%zd\n", sizeof(*a));//数组首元素地址解引用,表示数组首元素,4
    printf("%zd\n", sizeof(a+1));//第二个元素的地址,4/8
    printf("%zd\n", sizeof(a[1]));//第二个元素,4
    printf("%zd\n", sizeof(&a));//整个数组的地址,地址即指针4/8
    printf("%zd\n", sizeof(&a + 1));//地址,4/8
    printf("%zd\n", sizeof(&a[0]));//取出数组首元素地址,4/8
    printf("%zd\n", sizeof(&a[0] + 1));//数组第二个元素的地址4/8
    return 0;
}

字符数组:

代码1:

char arr[] = { 'a','b', 'c', 'd', 'e', 'f' };
printf("%zd\n", sizeof(arr));//整个数组的大小6
printf("%zd\n", sizeof(arr + 0));//指针4/8
printf("%zd\n", sizeof(*arr));//数组首元素,
printf("%zd\n", sizeof(arr + 1));//第二个元素的地址,4/8
printf("%zd\n", sizeof(arr[1]));//第二个元素,1
printf("%zd\n", sizeof(&arr));//整个数组的地址,地址即指针4/8
printf("%zd\n", sizeof(&arr + 1));//地址,4/8
printf("%zd\n", sizeof(&arr[0] + 1));//数组第二个元素的地址4/8

代码2:


    char arr[] = { 'a','b', 'c', 'd', 'e', 'f' };

    printf("%d\n", strlen(arr));//随机
    printf("%d\n", strlen(arr+0));//随机
    //printf("%d\n", strlen(*arr));//err报错
    printf("%d\n", strlen(arr+1));//随机
    printf("%d\n", strlen(&arr));//取出整个数组的地址,但还是从首元素地址开始,随机

代码3:

char arr[] = "abcdef";

printf("%d\n", sizeof(arr));//计算整个数组的大小,7(abcdef\0)
printf("%d\n", sizeof(arr+0));//arr数组首元素地址,arr+0还是首元素地址,地址即指针 ,4/8
printf("%d\n", sizeof(*arr));//arr数组首元素地址,*解引用后为a,等同arr[0],第一个元素,1
printf("%d\n", sizeof(arr[1]));//数组第二个元素,1
printf("%d\n", sizeof(&arr));//整个数组的地址类型为int (*)[7],4/8
printf("%d\n", sizeof(&arr+1));//跳过整个arr地址,指向f后的地址,指针,4/8
printf("%d\n", sizeof(&arr[0]+1));//取出第一个元素的地址后+1,即指向第二个元素的地址,指针,4/8

代码4:

    char arr[] = "abcdef";

    printf("%d\n", strlen(arr));//数组名,数组首元素地址,6
    printf("%d\n", strlen(arr+0));//数组首元素地址,6
// printf("%d\n", strlen(*arr));//数组首元素地址解引用,数组首元素a,a的ascll值为97,报错arr
// printf("%d\n", strlen(arr[1]));//第二个元素,b,98,arr
    printf("%d\n", strlen(&arr));//取出整个数组的地址,但还是从首元素地址a的地址开始,6
    printf("%d\n", strlen(&arr+1));//跳过整个数组的地址,随机
    printf("%d\n", strlen(&arr[0]+1));//取出第一个元素的地址+1,指向第二个元素,5

代码5:

char* p = "abcdef";
printf("%zd\n", sizeof(p));//p中存放字符串首元素地址的指针,4/8
printf("%zd\n", sizeof(p + 1));//'b'的地址,指针,4/8
printf("%zd\n", sizeof(*p));//首元素a,1
printf("%zd\n", sizeof(p[0]));//首元素,1
printf("%zd\n", sizeof(&p));//&p是二级指针,char**类型,4/8
printf("%zd\n", sizeof(&p + 1));//4/8
printf("%zd\n", sizeof(&p[0] + 1));//取字符串首元素地址+1,'b'的地址,4/8

代码6:

    char* p = "abcdef";
    printf("%zd\n", strlen(p));//p中存放字符串首元素地址,6
    printf("%zd\n", strlen(p+1));//'b'的地址,5
//    printf("%zd", strlen(*p));//首元素a,ascll 97,arr
//    printf("%zd\n", strlen(p[0]));//同*p,arr
    printf("%zd\n", strlen(&p));//二级指针,p的地址,随机
    printf("%zd\n", strlen(&p+1));//随机
    printf("%zd\n", strlen(&p[0]+1));//取首元素地址+1,同p+1,5

二维数组:

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]));//a[0]是第一行,一维数组的数组名,sizeof(数组名)计算一维数组的大小,16
printf("%d\n", sizeof(a[0]+1));//重点,a[0]一维数组数组名,表示a[0][0]的地址,指针,4/8
printf("%d\n", sizeof(*a[0]+1));//第二行第二个元素,4
printf("%d\n", sizeof(a+1));//a[0][1]的地址,4/8
printf("%d\n", sizeof(*(a+1)));//*(a+1)等同于a[1],是第二行数组名,计算的是第二行的大小,16
printf("%d\n", sizeof(&a[0]+1));//取一维数组a[0]的地址,+1即第二行数组a[1]的地址,4/8
printf("%d\n", sizeof(*(&a[0]+1)));//重点,访问第二行,计算第二行的大小,16
printf("%d\n", sizeof(*a));//第一行的地址,*a就是第一行等同a[0],16
printf("%d\n", sizeof(a[3]));//重点,sizeof只计算类型,不参与真实计算,故不存在越界,计算第四行的大小,16

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值