免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12345下一页
最近访问板块 发新帖
查看: 10075 | 回复: 45
打印 上一主题 下一主题

[C] 问一道关于指针的面试题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-10-15 23:40 |只看该作者 |倒序浏览
File1: main.c

char *pt[] = {
  "PT_DATA_COMM",
  "PT_DATA_CONN_CLOSE",
  "PT_DATA_SERV"
};

main() {
  printf ("print result1 = %d\n", pt[0]);
  fun1();
  fun2();
}

void fun1() {
  char** t = pt;
  printf ("print result2 = %d\n", t[1]);
}

File method.c

extern char** pt;
void fun2() {
  printf ("print result3 = %d\n", pt[2]);
}
编译 "gcc -o test main.c method.c"
运行 test
如果 第一行结果是 print result1 = 132514900, 那第二、三行是什么? 为什么?

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
2 [报告]
发表于 2011-10-15 23:43 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
3 [报告]
发表于 2011-10-16 00:00 |只看该作者
char *pt[] = {
  "PT_DATA_COMM",
  "PT_DATA_CONN_CLOSE",
  "PT_DATA_SERV"
};
指针数组指向rdonly data,
result2 =132514900+sizeof(int)
result3 =132514900+2*sizeof(int)

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
4 [报告]
发表于 2011-10-16 00:10 |只看该作者
本帖最后由 OwnWaterloo 于 2011-10-16 00:11 编辑

回复 3# lwrsmy

1. 按照你的想法,也不应该是sizeof(int),而是sizeof(char*)。

2. 你的想法是错的
第2行根本没有可预测的结果
如果是输出 —— 需要用%p而非%d输出 —— &pt[0], &t[1] , 它们之间的差值才能确定是 sizeof(char*) 。

3. 我猜测第3行才是出题者的key point —— 通过指针访问比通过数组访问多一层间接性
可惜他的水平不足以使题目本身正确

论坛徽章:
2
程序设计版块每日发帖之星
日期:2015-06-17 22:20:00每日论坛发贴之星
日期:2015-06-17 22:20:00
5 [报告]
发表于 2011-10-16 00:12 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
6 [报告]
发表于 2011-10-16 00:31 |只看该作者
回复  lwrsmy

1. 按照你的想法,也不应该是sizeof(int),而是sizeof(char*)。

2. 你的想法是错的
第 ...
OwnWaterloo 发表于 2011-10-16 00:10


指针表示计算机的位数,int型大小就是指针位数

三个连续的常量在可读存储区是连续存储的,当然你也可以说他不是。


void fun1() {
  char** t = pt;
  printf ("print result2 = %d\n", t[1]);
}
结果不可能不可预知,t[1]也不会造成程序崩掉,t[1]=t+sizeof(char*)

论坛徽章:
0
7 [报告]
发表于 2011-10-16 00:32 |只看该作者
%d %p都是按整型表示,实际上内存中只要类型解释方法一样,结果就是一样的

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
8 [报告]
发表于 2011-10-16 00:36 |只看该作者
回复 6# lwrsmy

我觉得编程人员成长的主要几个障碍:
1. 抵触英文
2. 不愿意修正自己已有的认识,总认为自己一旦有了见解就一定是对的,总是对的,永远是对的。
3. 逻辑有问题
……

你已经占了两条了。

论坛徽章:
0
9 [报告]
发表于 2011-10-16 00:49 |只看该作者
本帖最后由 x5miao 于 2011-10-16 01:53 编辑

回复 7# lwrsmy


(1) %d,%p的含义绝对不一样,int型和指针类型的位数也不一定一样;

(2) t[1]显然不等于t+sizeof(char *),因为他们的类型不一样,一个是char *一个是char **

(3)在通用的32位系统下,t+sizeof(char *)等于t+4等于&t[4],会发生越界

正确的程序应该是:
File1: main.c

  1. #include<stdio.h>

  2. char *pt[] = {
  3.   "PT_DATA_COMM",
  4.   "PT_DATA_CONN_CLOSE",
  5.   "PT_DATA_SERV"
  6. };
  7. void fun1(void);
  8. void fun2(void);

  9. int main(void)
  10. {
  11.     printf ("print result1 = %p\n", pt[0]);
  12.     fun1();
  13.     fun2();
  14.     return 0;
  15. }

  16. void fun1(void) {
  17.   char** t = pt;
  18.   printf ("print result2 = %p\n", t[1]);
  19. }
复制代码
File method.c

  1. #include <stdio.h>
  2. extern char* pt[];
  3. void fun2(void) {
  4.   printf ("print result3 = %p\n", pt[2]);
  5. }
复制代码
我电脑上的输出结果是
$gcc -o method main.c method.c -g -Wall
$./method
print result1=0x8048500
print result2=0x804850d
print result3=0x8048520

论坛徽章:
2
青铜圣斗士
日期:2015-11-26 06:15:59数据库技术版块每日发帖之星
日期:2016-07-24 06:20:00
10 [报告]
发表于 2011-10-16 00:55 |只看该作者
回复 6# lwrsmy

本来不想搭理你的,但等gcc编译实在太无聊了……


>> 指针表示计算机的位数,int型大小就是指针位数
>> %d %p都是按整型表示,实际上内存中只要类型解释方法一样,结果就是一样的

知道386之前的x86是什么情况吗?
指针是位数?
int型大小是指针位数?

知道64位机吗? int大小也是指针位数?

>> 三个连续的常量在可读存储区是连续存储的,当然你也可以说他不是。

先按你的想法:连续存储。
你说 pt[1] - pt[0] 应该是 :
1. sizeof(char*) (或者再按你的说法 sizeof(int) )呢
2. 还是 strlen("PT_DATA_COMM")+1 ?

可惜并没有谁规定常量是连续存储。考虑过:
1. 对齐吗?
2. 字符串字面量合并吗?
3. 字符串字面量排序后存放吗?

你还认为假设字符串字面量地址之间有什么联系在大多数情况下是合理的行为吗?


就你这水平,虚心点对你没坏处。
至于你是否接受,我可就没辙了,言尽于此。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP