C语言-----sizeof和strlen的计算

sizeof是一个关键字,求字符串所占的字节数。

  • sizeof在计算变量所占空间大小时,括号可以省略,但是绝对不能sizeof int,这是错误的,可以在int前加unsigned,const等关键字,但是不能加sizeof,以下三种都是正确的;
  • sizeof在编译的时候计算出来。
    printf("%d\n", sizeof(int));
    printf("%d\n", sizeof(a));
    printf("%d\n", sizeof a);

strlen是一个函数,求字符串的长度,结束符\0之前的字符个数。

  • 它的值在函数运行完后才求出来的

看一下下面几组练习:

**一维数组**
    int a[] = { 1, 2, 3, 4 }; 
    printf("%d\n", sizeof(a)); //16      sizeof(数组名)表示整个数组大小
    printf("%d\n", sizeof(a + 0)); //4   首元素地址
    printf("%d\n", sizeof(*a)); //4      首元素地址解引用拿到第一个元素1,int型
    printf("%d\n", sizeof(a + 1));//4    首元素地址+1指向第二个元素地址
    printf("%d\n", sizeof(a[1])); //4    第二个元素
    printf("%d\n", sizeof(&a)); //4      取整个数组的地址,4个字节
    printf("%d\n", sizeof(*&a)); //16    数组地址解引用访问整个数组
    printf("%d\n", sizeof(&a + 1)); //4  跳过整个数组到下一个数组的地址
    printf("%d\n", sizeof(&a[0])); //4   第一个元素的地址
    printf("%d\n", sizeof(&a[0] + 1));//4 第二个元素的地址

**字符数组**
    char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' }; 
    printf("%d\n", sizeof(arr));//6      sizeof(数组名)表示整个数组大小 
    printf("%d\n", sizeof(arr + 0));//4  首元素地址
    printf("%d\n", sizeof(*arr)); //1    首元素地址解引用拿到第一个元素1,char型
    printf("%d\n", sizeof(arr[1]));//1   第二个元素
    printf("%d\n", sizeof(&arr)); //4    取整个数组的地址
    printf("%d\n", sizeof(&arr + 1));//4 跳过整个数组到下一个数组的地址
    printf("%d\n", sizeof(&arr[0] + 1));//4 第二个元素地址
    printf("%d\n", sizeof(*&arr));//6    数组地址解引用访问整个数组

    printf("%d\n", strlen(arr)); //随机值x
    printf("%d\n", strlen(arr + 0)); //随机值x
    printf("%d\n", strlen(*arr)); //错误,*arr取的是a的ASCII码值97,在去访问地址为97的这块空间,不允许访问
    printf("%d\n", strlen(arr[1])); //错误,理由同上
    printf("%d\n", strlen(&arr)); //随机值x
    printf("%d\n", strlen(&arr + 1)); //随机值x-6
    printf("%d\n", strlen(&arr[0] + 1));//随机值x-1

    char arr[] = "abcdef"; 
    printf("%d\n", sizeof(arr)); //7       表示整个数组大小 abcdef\0
    printf("%d\n", sizeof(arr + 0)); //4   表示首元素地址
    printf("%d\n", sizeof(*arr)); //1      首元素地址解引用
    printf("%d\n", sizeof(arr[1]));//1     第二个元素的大小
    printf("%d\n", sizeof(&arr)); //4      取整个数组的地址
    printf("%d\n", sizeof(&arr + 1));//4   跳过整个数组到下一个数组的地址
    printf("%d\n", sizeof(&arr[0] + 1));//4 第二个元素的地址
    printf("%d\n", sizeof(*&arr));//7  数组地址解引用访问整个数组

    printf("%d\n", strlen(arr)); //6
    printf("%d\n", strlen(arr + 0));//6 
    printf("%d\n", strlen(*arr)); //错误
    printf("%d\n", strlen(arr[1])); //错误
    printf("%d\n", strlen(&arr)); //6   取首地址
    printf("%d\n", strlen(&arr + 1)); //随机值
    printf("%d\n", strlen(&arr[0] + 1));//5   从第二个元素数直到\0

    char *p = "abcdef"; 
    printf("%d\n", sizeof(p)); //4   p是一个指针
    printf("%d\n", sizeof(p + 1));//4   第二个元素b的地址 
    printf("%d\n", sizeof(*p)); //1    p中存放了a的地址,解引用找到a,a是char类型的
    printf("%d\n", sizeof(p[0])); //1  第二个元素大小,相当于*(p+0)
    printf("%d\n", sizeof(&p)); //4    取指针变量p的地址
    printf("%d\n", sizeof(&p + 1));//4   
    printf("%d\n", sizeof(&p[0] + 1));//4   取第二个元素的地址,即b的地址

    printf("%d\n", strlen(p));//6  遇到\0停止
    printf("%d\n", strlen(p + 1)); //5 p+1指向b这个元素,从b开始往后走遇到\0就停下
    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  第一个元素地址+1指向第二个元素地址,从b开始往后走遇到\0就停下,跟strlen(p + 1)同理

    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   a[0]第一行数组的大小
    printf("%d\n", sizeof(a[0] + 1)); //4 第一行数组第二个元素的地址
    printf("%d\n", sizeof(a + 1)); //4   降级为首元素地址(第一行地址)跳过16个字节到第二行的地址
    printf("%d\n", sizeof(&a[0] + 1)); //4  第二行地址
    printf("%d\n", sizeof(*a)); //16  降级为首元素地址(第一行地址)解引用
    printf("%d\n", sizeof(a[3]));//16 sizeof()内部表达式不计算,数组名单独放在sizeof内部跟第一行数组大小一样还是16个字节

以下三点要好好记住并理解含义:


    1.sizeof(数组名)————数组名表示整个数组,求整个数组大小,单位:字节
    2.&数组名————取整个数组的地址
    3.除此之外,所有遇到的数组名都是首元素地址
strlen(arr),参数是地址,从这个地址往后找遇到\0停止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值