• 面试经典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 <stdio.h>
      
      int main()
      
      {
      
      	int a[5]={1,2,3,4,5};
      
      	a++;
      
      }

      image
      提示只有左值(lvalue)才能自增。而对于以函数名作为参数输入时,这一常量特性消失,如下面代码运行就没有问题:
      #include <stdio.h>
      
      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 <stdio.h>
      
      void Func(int a[5]);
      
      int main()
      
      {
      
      	int a[5]={1,2,3,4,5};
      
      	printf("The value of a is %X\n",a );
      
      	printf("The value of &a is %X\n", &a);
      
      	printf("The value of a+1 is %X\n",a+1 );
      
      	printf("The value of &a+1 is %X\n",&a+1 );
      
      	int *p1=(int *)(a+4);
      
      	printf("%d\n",p1[-1] );
      
      	printf("%d\n",((int *)(a+4))[-1] );
      
      	int *p2=(int *)(&a+1);
      
      	printf("%d\n",p2[-1] );
      
      	//printf("%s\n",((int *)(&a))[1] ); //加上这句话会出错
      

      相应的输出如下:
      image
      可以看出a和&a数值上是一样的,&a+1相较于a多了20个字节的距离,这正好是一个数组的长度。
    3. sizeof(a)不是指针所占空间的大小,而是指数组a所占空间的大小。
  • 相关阅读:
    宏大的目标
    java tcp ip网络编程(二) 套接字的基本使用
    java socket编程(一)简介
    是么是 API 和 SDK
    Mac 下显示隐藏文件
    iOS-事务相关
    iOS测试一段代码的运行时间
    sqlite3 语句总结
    iOS-scrollview及其子类适配iOS7
    OAuth2.0授权和SSO授权
  • 原文地址:https://www.cnblogs.com/obama/p/3027060.html
Copyright © 2020-2023  润新知