zoukankan      html  css  js  c++  java
  • 比较分析与数组相关的sizeof和strlen

    首先,我们要清楚sizeof是C/C++中的一个操作符,其作用就是返回一个对象或者类型所占的内存字节数。

    而,strlen是一个函数,函数原型为:

    size_t strlen(const char *string);

     strlen函数的作用是:计算给定字符串的长度,不包括''在内

    // 数组形如:
    int a[]={1,2,3,4,5};
    char name[]="abcdef";

    无论是整型数组还是字符数组,数组名作为右值的时候都代表数组首元素的首地址。

    数组发生降级(数组名退化为数组首元素的地址)的情况:数组传参、数组名参与运算

    数组名不会发生降级的情况:sizeof(数组名)、取地址数组名(取到的是整个数组的地址而不是首元素的地址)

    (以下结果都经过VS2013验证)

    我们先来定义两个整型数组:

    int a[] = { 1, 2, 3, 4 };
    int p[5] = { 1, 2, 3, 4 };
    printf("%d
    ", p[4]);
    printf("%d
    ", sizeof(p));        //20
    printf("%d
    ", sizeof(a));        //16

    数组a未定义数组的大小,sizeof(a)的结果是16;数组p定义了数组的大小,sizeof(p)的结果是20,系统会默认将p[4]初始化为0;不论是a还是p,都求的是整个数组的大小

    sizeof(a)其中有四个整型,一个整型4个字节,4*4=16个字节

    int a[] = { 1, 2, 3, 4 };
    printf("%d
    ", sizeof(a + 0));    //4

    因为数组名a参与运算发生了降级,变为首元素的地址,a+0依旧是首元素的地址,相当于求sizeof(&a[0]) ,而一个地址本身是四个字节

    int a[] = { 1, 2, 3, 4 };
    printf("%d
    ", sizeof(*a));     //4    对首元素的地址进行解引用取到首元素的值,为int型
    printf("%d
    ", sizeof(a + 1));  //4    sizeof(&a[1])
    printf("%d
    ", sizeof(a[1]));   //4    数组的每个元素都是整型
    printf("%d
    ", sizeof(&a));     //4 取到整个数组的地址(地址为四个字节存储)
    printf("%d
    ", sizeof(&a + 1));         //4    地址的大小为四个字节
    printf("%d
    ", sizeof(&a[0]));          //4    地址的大小为四个字节
    printf("%d
    ", sizeof(&a[0] + 1));      //4    地址的大小为四个字节
    printf("%d
    ", sizeof(*&a));          //16   &a取到整个数组的地址,再解引用取到整个数组

     sizeof(&a)在高版本的编译器下结果都为4,在低版本如VC6.0中为16(这或许是VC6.0的一个BUG)

    分析了int型数组的情况,我们再来看看char型数组的情况:

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
     
    char name1[10];         //定义全局性数组 系统默认初始化为''
    int main()
    {
               char name[10];
               printf("%d
    " , sizeof(name));    // 10
               printf("%d
    " , strlen(name));     // 随机值
     
               printf("%d
    " , sizeof(name1));    // 10
               printf("%d
    " , strlen(name1));     // 0        
               system("pause" );
               return 0;
    }

     定义在全局的数组,及时你没有初始化,系统也会默认初始化为0,而name1在这里是char类型,所以编译器会自动把它初始化为"".

    sizeof(name)依旧算的是数组的大小,而strlen是遇到""就结束

    由于name没有初始化,strlen(name)的结果是个随机值,什么时候遇到"",就什么时候停下来。 

    //***********************************************************************************//
     
    char name[] = "abcdef" ;             // 6个字符还有一个""
    printf("%d
    " , sizeof(name[0]));    // 1  name[0]='a'  char一个字节存储
    printf("%d
    " , sizeof(&name));      // 4  取到整个数组的地址  地址为四字节存储
    printf("%d
    " , sizeof(*name));      // 1   
    printf("%d
    " , sizeof(&name + 1));  // 4  地址! (把整个数组都跳过去了)
    printf("%d
    " , sizeof(name + 1));   // 4  数组名参与运算降级为地址 ==> sizeof(&a[1])
    printf("%d
    " , sizeof(name));       // 10    数组的大小
    printf("%d
    " , strlen(name));       // 6     遇到''就结束
    printf("%d
    " , strlen(&name));      // 6   
    //printf("%d
    ", strlen(*name));     // 无效,不能strlen字符
    printf("%d
    " , strlen(&name + 1));  // 随机值 
    printf("%d
    " , strlen(name + 1));   // 5  为跳过首元素后的"bcdef"的长度
     
    //***********************************************************************************//

    strlen(&name) :strlen函数一个字符一个字符跳转,直到遇到''才结束。 这里编译器进行隐式的强制类型转换成char*,相当于在求strlen(name)

    strlen(&name + 1):这是一个随机值,因为&name + 1把整个数组都跳过去了,传给strlen的参数是name数组后面未可知的地址,strlen会一直走下去,直到遇到""

    sizeof(*name):name发生降级,变为首元素的首地址,再解引用取到字符'a'(*name='a'),输出1

    2016-04-12 16:24:56

  • 相关阅读:
    php判断远程图片是否防盗链
    php获取远程图片url生成缩略图的方法
    qq zone g_tk
    zend studio aptana
    qq音乐接口
    function https_request
    Eclipse 汉化
    php 邮箱替换*
    获取顶级域名函数
    weixin oauth api 使用
  • 原文地址:https://www.cnblogs.com/Lynn-Zhang/p/5383201.html
Copyright © 2011-2022 走看看