栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > C++面试题库

腾讯春季实习生招聘笔试-C语言之数组名分析

在腾讯春季实习生招聘笔试的时候遇到这么一个问题:

给定一个数组int a[10]; 下面哪些不可以表示a[1]的地址?
A. a+sizeof(int)
B. &a[0]+1
C. (int*)&a+1 
D.(int*)((char*)&a+sizeof(int))

对于这个题目,我当时的分析是这样的,对于数组名a,它是一个int*指针常量,指向数组第一个元素的地址,既然是指针常量,a+sizeof(int)即为a+4,肯定是不可以表示a[1]的,B显然是可以的,对于C答案,就出现疑惑了,对一个指针取地址应该是int **类型,那么(int*)&a 应该表示指向存放a指针的区域的指针,看起来好像与a[1]毫不相干,所以C应该是不行的(实际证明是可以的),对于D答案,同样的道理,好像是不行的,因此答案似乎是ACD.

出人意料的是,答案尽然是A而已,这是为什么?

好吧,那是因为&a和a指向的是同一地点,如果有这个结论,得到答案A就不足为奇了。我记起来当初学sizeof函数的时候,向当时教C语言的老曹头问过了一个问题,为什么sizeof(a)的值不是4而是数组的大小呢,比如说这个例子里面就是20而不是4,那么,关于数组名,到底有哪些特性呢?

  1. 数组名是一个指针常量,指向数组的第一个元素,但是当数组作为参数传入函数时,数组名的这一特性消失,可以做自增自减等操作。
    例如,对于下面这段代码:
    #include 
    int main()
    {
    int a[5]={1,2,3,4,5};
    a++;
    }


    image

    提示只有左值(lvalue)才能自增。而对于以函数名作为参数输入时,这一常量特性消失,如下面代码运行就没有问题:

    #include 
    void Func(int a[5]);
    int main()
    {
    int a[5]={1,2,3,4,5};
    Func(a);
    }
    void Func(int a[5])
    {
    a++;
    }

  2. 数组名和数组名取地址的指向的位置是一样的,但是它们有区别,以上面声明的int a[10]为例,a表示指向整数的指针,而&a表示指向数组的指针,下面这段代码清楚地说明了这一问题:
    #include 
    void Func(int a[5]);
    int main()
    {
    int a[5]={1,2,3,4,5};
    printf("The value of a is %Xn",a );
    printf("The value of &a is %Xn", &a);
    printf("The value of a+1 is %Xn",a+1 );
    printf("The value of &a+1 is %Xn",&a+1 );
    int *p1=(int *)(a+4);
    printf("%dn",p1[-1] );
    printf("%dn",((int *)(a+4))[-1] );
    int *p2=(int *)(&a+1);
    printf("%dn",p2[-1] );
    //printf("%sn",((int *)(&a))[1] ); //加上这句话会出错

    相应的输出如下:

    image

    可以看出a和&a数值上是一样的,&a+1相较于a多了20个字节的距离,这正好是一个数组的长度。

  3. sizeof(a)不是指针所占空间的大小,而是指数组a所占空间的大小。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/265258.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号