[转]解读C指针(5)——笔试题解析

原文地址:http://blog.csdn.net/czmpersist/article/details/11846223

        前面已经详细讲述了指相关的概念,相信大家也理解了,下面来点真枪实战的,看看各大公司笔试题吧!

 1.定义一个函数指针,指向的函数有两个int形参并且返回一个函数指针,返回的指针指向一个有一个int形参且返回int的函数?(阿里笔试题)
Aint (*(*F)(int, int))(int)      B、int (*F)(int, int)          C、int (*(*F)(int, int))          D、*(*F)(int, int)(int)

          解析:看完题目以后,不知道大家会选择哪个答案,请读者仔细想想。

step1:定义一个函数指针,指向的函数有两个int形参,可知 :  (*F)(int, int)

step2:返回一个指针,可以表示为 Type * (*F)(int, int),Type且认为是一种类型

step3 :返回的指针指向一个一个有一个int形参且返回int的函数,假设指针为T,则int (* T)(int),其中的T是一个指针,而这个指针正好是(*F)(int, int)函数所返回的指针,所以题目的正确答案是:int (*(*F)(int, int))(int) 。

再来看看其他选项的答案:

选项B表示 F是一个指向有两个int形参且返回int类型的函数的指针;

选项C表示 F是一个指向有两个int形参且返回int类型的函数的指针的指针;

选项D则是一个错误的表达式。


2、声明一个指向含有10个元素的数组的指针,其中每个元素是一个函数指针,该函数的返回值是int,参数是int*,正确的是()(阿里笔试题)
A、(int *p[10])(int*)      B、int [10]*p(int *)        C、int (*(*p)[10])(int *)          D、int ((int *)[10])*p 
             解析:看完题目以后,仔细想想,该会是那一个呢?

step1:一个指向含有10个元素的数组的指针,这个前面分析过,所以很简单:(*P)[10];

step2:每个元素是一个函数指针,该函数的返回值是int,参数是int*,先定义一个元素T,很简单:int (* T)(int *)

step3:T其实就是数据中的一个元素,二者组合就可以了,正确的答案是:int (*(*P)[10])(int *)。

再来看看其他选项的答案:

选项A是错误定义;选项B也是错误的表示方式;选项D错误的表示方式。


3、以下程序片断运行后,输出的结果是多少?(锐捷笔试题)

int a[3][2] = {{10,20}, {30,40}, {50,60}}, (*p)[2];

p = a;

printf("%d", *(*(p+1)+2) );

再加2个,如果要输出表达*(*(p+2)+3),*(*(p+3)+1)会是多少呢?

      有人会想,这还不简简单,三个都不对,出现编辑错误。但是编译器什么友好,没有任何错误的提示(一般情况下)。这是为什么呢?看下面来分析:

       首先要搞清楚的是:p的类型是int (*)[2],p指向的是int [2],即含有两个整形元素的整形数组;既然知道指针所指向的类型,就明白p指针运算的意义,明确的说(p + 1)在内存中,实际是p在内存中的值加上 1 * sizeof(int [2]);

       而*p其实的类型实际是int *,它指向一个整形数,那么(*p + 2)就很好理解了,则是*p在内存中的值加上2*sizeof(int),说到这里,你也也许明白了,好,我们再来看题。

  设想对数组a来说,a代表数组首地址是常量,这都知道,假设这个值为S;同样的p值也为S;

(p+1)的值在内存中实际为:S + 1 * sizeof(int [2]) = 8;      (注意这是一个地址)

*(p+1)+2的值在内存中实际为:S + 1 * sizeof(int [2])  + 2 * sizeof(int) ;   (注意这是一个地址)

所以*(*(p+1)+2)实际是p向下移动了5个位置,而所谓的二维数据其实在内存中是以一维数组的形式存储的,所以实际的值应为50; 而*(*(p+2)+3) = S + 2 * sizeof(int [2])  + 3 * sizeof(int) ;共移动了7个整形数位置,超出了数组的赋值的范围,所以值不确定;同理*(*(p+3)+1) =  S + 3 * sizeof(int [2])  + 1 * sizeof(int) ;也移动了7个整形数位置,所言值不确定。

      通过这个例子提醒各位,使用数组的指针时一定要对指针相当熟悉,认真分析指针的类型,指向的类型,指针变量存放的值,及指针本身占据内存的空间,如上面指 针超出范围以后,编译器并没有提示错误,如果程序较大的话很难发现,给程序留下BUG,而且这种BUG很难发现!


        好了,结合实例给大家分享了几个关于指针的题目,要熟练掌握指针还得从关键概念着手,一步一步,这样才能理解深刻。

原文地址:https://www.cnblogs.com/minghang/p/5614634.html