|
|
|
|
移动端

1.6.1 指针(1)

《程序员面试笔试真题与解析》本书针对当前各大 IT企业面试笔试中特性与侧重点,精心挑选了 3年以来近百家典型 IT企业的面试笔试真题,这些企业涉及业务包括系统软件、搜索引擎、电子商务、手机 APP、安全关键软件等,面试笔试真题非常具有代表性与参考性。本节为大家介绍指针。

作者:猿媛之家来源:机械工业出版社|2017-12-06 13:42

年前最后一场技术盛宴 | 1月27日与京东、日志易技术大咖畅聊智能化运维发展趋势!


1.6 指针与引用

1.6.1 指针(1)

【真题 47】 int *p = &n;,那么*p的值是()。

A.p的值 B.p的地址 C.n的值 D.n的地址

答案:C。

【真题 48】下列 C语言代码中,属于未定义行为的有()。

A.int i=0;i=(i++); B.char *p="hello";p[1]= ‘E’;

C.char *p="hello";char ch=*p++; D.int i=0;printf("%d%d\n",i++,i--);

E.都是未定义行为 F.都不是未定义行为答案:B。本题中,选项 A、选项 C和选项 D都能编译并且正确运行,但是选项 B却属于未定义行为,在

选项 B中,p是一个指向 const char的指针,它指向的东西不能被改变,由于修改了它指向的字符,所以,选项 B不正确。相对而言,选项 C中没有改变 p所指向的东西,只是修改了 p指针,所以,选项 C正确。

【真题 49】有如下代码:

  1. int main(int argc, char **argv)  
  2. {  
  3. int a[4] = { 1, 2, 3, 4 };  
  4. int *ptr = (int *)(&a + 1);  
  5. printf("%d", *(ptr - 1));  

程序的输出结果是()。

A.1 B.2C.3D.4 答案:D。 &a+1不是首地址 +1,系统会认为加了一整个 a数组,偏移了整个数组 a的大小(也就是 4个 int的

大小)。所以,语句 int *ptr=(int *)(&a+1);执行完后,ptr实际是&(a[4]),也就是 a+4。&a是数组指针,其类型为 int(*)[4],而指针加 1要根据指针类型加上一定的值,不同类型的指针 +1之后增加的大小不同, a是长度为 4的 int数组指针,要加 4*sizeof(int),所以, ptr实际是 a[4],但是 ptr与(&a+1)的类型是不一样的,这点非常重要,所以, ptr-1只会减去 sizeof(int)。a与&a的地址是一样的,但意思就不一样了, a是数组首地址,也就是 a[0]的地址,&a是对象(数组)首地址, a+1是数组下一元素的地址,即 a[1], &a+1是下一个对象的地址,即 a[4]。接着把 &a+1转换为指向 int的指针,因此, ptr-1指向 a[3],所以,程序的输出结果为 4。

【真题 50】在 C++语言中,有如下代码:

  1. const int i = 0;  
  2. int *j = (int *)&i;  
  3. *j = 1;  
  4. printf("%d, %d", i, *j); 

程序的输出结果是( )。

A.0,1  B.1,1  C.1,0  D.0,0

答案:A。

本题中,对于赋值语句 const int i = 0,i表示的是一个常量,因此,对常量 i的值进行修改是不被允许的(例如 i=1是不允许的),但是可以通过获取 i的指针来修改 i的值,即用这个指针来修改 i的值。对于赋值语句 int *j = (int *)&i,它表示的是获取到 i的地址给变量 j,然后执行*j=1操作,通过该语句,实际上间接地修改了常量 i的值。由于 i是个常量,通常编译器在优化阶段都会把所有出现 i的地方替换为 0,因此,语句 printf("%d, %d", i, *j)实际上等价于 printf("%d, %d", 0, *j),输出结果为 0,1。所以,选项 A正确。

【真题 51】定义一个 int类型的指针数组,数组元素个数为 10个。以下定义方式中,正确的是()。

A.int a[10]; B.int (*a)[10]; C.int *a[10]; D.int (*a[10])(int); 答案:C。在 C/C++语言中,数组指针是指向数组地址的指针,其本质为指针。指针数组指的是数组元素全为

指针的数组,其本质为数组,例如 int *p[3];,定义了 p[0]、p[1]、p[2]三个指针。一维指针数组的定义形式为:“类型名 *数组标识符 [数组长度]”。例如,定义一个一维指针数组: int *array[10];。

本题中,对于选项 A,表示的是 int类型的数组,选项 B表示的是 int类型的数组的指针,选项 C表示的是 int类型的指针的数组,选项 D表示的是函数指针的数组, []优先级高于*,说明 a是一个数组,数组元素的类型为函数指针。所以,选项 A错误。

对于选项 B,运算符“ ()”的优先级比运算符“ []”高,为了便于理解,在这里引入一个临时变量 tmp,那么语句 int (*a)[10];可以等价为: int tmp[10]; tmp=*a;,由此可以得出 a=&tmp。显然, a是 int类型的数组的指针,它指向一个包含 10 个 int 类型数据的数组,即 a是一个数组指针。所以,选项 B错误。

对于选项 C,a先与“ []”结合,构成一个数组的定义,数组名为 a,int *修饰的是数组的内容,即数组的每个元素。因此, a是一个指针数组,包含 10个指向 int 类型数据的指针。所以,选项 C正确。

对于选项 D,同样可以采用引入临时变量的方法来理解。对于一个函数 int f(int),定义这个函数的一个函数指针 p的写法为:int (*p)(int);,p就是一个函数的指针,把 p改成 a[10],则说明定义了一个大小为 10的数组,数组中存放的是返回值 int且参数为 int的函数指针。所以,选项 D错误。

【真题 52】若已定义: int a[9], *p = a;,并在以后的语句中未改变 p的值,不能表示 a[1]地址的表达式是()。

A.++p B.a+1  C.p+1 D.a++答案: D。 a和 p都指向数组的首元素 a[0],显然,a+1与 p+1都指向 a[1]。因此,选项 B和选项 C正确。对于选项 A,++p是首先执行 ++操作,它的结果也就等价于 p+1,也指向 a[1]。因此,选项 A正确。对于选项 D,为了便于理解,可以引入一个临时变量 int* tmp=a++;,这行代码执行的结果为: tmp

仍然指向 a[0],当这行代码结束运行后才执行 a的自增操作,此时 a才指向 a[1]。由此可见, a++的值仍然是指向 a[0]的指针。因此,选项 D错误。

【真题 53】下面程序的运行结果是()。

  1. #include<stdio.h> 
  2. int main()  
  3. {  
  4. int a[5] = { 1, 2, 3, 4, 5 };  
  5. int *p, **k;  
  6. p = a;  
  7. k = &p;  
  8. printf("%d ", *(p++));  
  9. printf("%d", **k);  
  10. return 0;  

A.11 B.21 C.22 D.12

答案:D。

本题中,p是指向数组 a的指针, k是指向指针 p的指针。第一次 printf的时候由于 p++是后置++操作,因此,首先输出 *p的值 1,接着完成 p的自增操作,因此, p指向数组的第 2个元素,此时: *k的值即为 p的值,而 **k的值即为*p的值,也就是数组元素 a[1]的值了。所以,选项 D正确。引申:有如下代码:

  1. #include<stdio.h> 
  2. #include<stdlib.h> 
  3. int main()  
  4. {  
  5. int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, }, k, *p = a + 5, *q = &k;  
  6. *q = *(p + 5);  
  7. printf("%d %d\n", *p, *q);  
  8. return 0;  

程序的输出是()。

答案:6,11。

*p=a+5表示的是指针 p指向数组 a的第六个元素,即 *p值为 6。*q=&k,则 q是 k的别名,和 k是同一个值。 *q = *(p+5),则*q的值是从 p开始再往后 5个,即 *q值为 11,此时 k的值也会被修改为 11。

喜欢的朋友可以添加我们的微信账号:

51CTO读书频道二维码


51CTO读书频道活动讨论群:365934973

【责任编辑:book TEL:(010)68476606】

回书目   上一节   下一节
点赞 0
分享:
大家都在看
猜你喜欢

读 书 +更多

网络管理员考试全真模拟试题与解析

本书是按照全国计算机技术与软件专业技术资格(水平)考试《网络管理员考试大纲》的要求,参照《网络管理员教程》及近年来考试试题编写的。...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊