| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1652 人关注过本帖, 4 人收藏
标题:【新手向 大牛慎入】【瞎眼向】【内有指针妹子玉照】单纯的指针妹子和她的狐 ...
只看楼主 加入收藏
lz1091914999
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:四川
等 级:贵宾
威 望:37
帖 子:2011
专家分:5959
注 册:2010-11-1
收藏
得分:0 
国内很多的公司呢,面试的时候为了检测你对C的了解程度,就会出这种类型的题。并且出的这些题呢有这些特点:
1、运算符优先级问题。
2、类型之间的转换及无符号和有符号运算问题。
3、大端和小端及内存分配问题(比如一个变量它在内存里是怎么表现的、结构体对齐、malloc等)。
4、宏问题。
5、其它(大家都知道天朝人民的创意是无限的)。

这段代码就具有1和3的特点,3是我加的,我先说说1吧:
"[]"看到这个东西可能大家马上就联想到了数组,没错定义一个数组没它是不行的,并且它还是一个运算符(下标运算符),数组名通过它加一个整数的参数(偏移量)就可以访问到该数组的某一个元素。如果a是一个数组,那么a[1]就是该数组的第一个元素。并且a[1]和*(a+1)是一样的,因为数组名a其实就是该数组第一个元素的指针嘛。记得谭浩强教授的书里管它叫“变址运算符”,其实也就是为了解释它和指针之间的关系。

介绍就到这里,不懂的同学还得好好看看书。
1["abc"]

那么这个大家应该明白了吧,如果转换成指针的话应该是这样的:
*(1+"abc")

首先1+"abc"结果就是字符b的地址。前面还有一个'*',这个运算符大家都懂的,它出现在指针的左边代表“间接引用这个地址里的值”,所以我喜欢叫它“间接引用(dereference)运算符”,有些叫兽管它叫“解引运算符”,其实是错的,错误的原因在于它把dereference翻译成了“解引用”。其实它自己都不知道这个单词的准确意思,只好借助于一些翻译工具等,返回的结果是可想而知的。  说了那么多,1["abc"]其实就是间接引用到了字符'b',所以它的结果就是字符'b'。
好了,那么这个呢:
&6["Hello,What is that?\n%s"]

这里又出现了一个'&'(取址运算符),这里就和第1点,运算符优先级的问题有关了。baidu一下你就知道'&'的优先级是比"[]"的优先级低的,其实不查你也应该知道,因为"&6"这个代码是错误的,因为不能对一个“字面整数常量”进行取址操作。所以应该先是执行的"6["Hello,What is that?\n%s"]"然后才是对这个运算的结果进行取址。整理一下就是:
&*(6+"Hello,What is that?\n%s")

结果就是字符'W'的地址,那么它就是子字符串"What is that?\n%s",前面的"Hello,"被跳过了。

看了运行结果的朋友现在应该猜到了,sizeof(X)=4,sizeof(Y)=6, sizeof(Z)=8。
当然这段代码只能在x86,也就是你定义一个int它的大小是4个字节上的环境上运行。如果不是那么就达不到预期的效果了,看了下面的解释之后你就明白了。

那么这就是第4点,结构体对齐问题有关了,比如你定义一个结构体:
程序代码:
struct X {
    int a;
    short b;
    short c;
};

如果int是4个字节,那么short就应该是2个字节,很多书上说结构体的大小就是所有字段的总和,所以sizeof(struct X);应该返回8。你运行一下,应该返回的是8。那么书上说的就是正确的吗?其实不然,如果你改变一下位置:
程序代码:
struct X {
    short b;
    int a;
    short c;
};

现在sizeof(struct X);就会返回12,它在内存里面应该是这样的:
b|**XX|
a|****|
c|**XX|
*代表实际占用的空间,X代表实际未被使用的空间(空洞),之所以会这样是因为编译器为了提高访问某一个字段的效率。
而刚才那个未改变顺序之前的结构体的内存结构应该是这样的:
a|****|
.|****|
  ^ ^
  b c
b的后面紧跟着两个字节的c。
由于对齐的原因,结构体的大小实际上跟占用空间最大的那个字段有关,大小往往是它的整数倍。有趣的是,在定义结构的时候可以简单的按从大到小的顺序来安排每个字段便可以节省更多的空间。当然一般情况下没必要,如果这样安排会影响结构的可读性的话,那就更没必要了。

还有结构体对齐不一定所有编译器都会这样做,说不定有些聪明的编译器有更好的方法。

至于第2点和第4点以及第3点的其它问题,还是让Z版来给大家介绍吧!

[ 本帖最后由 lz1091914999 于 2012-12-2 00:30 编辑 ]

My life is brilliant
2012-12-02 00:25
embed_xuel
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
等 级:贵宾
威 望:58
帖 子:3845
专家分:11385
注 册:2011-9-13
收藏
得分:0 
别人要问我指针,第一件事就是做这个
int a=10;
int *p = &a;
把p,*p,&p,a,&a,都打印出来琢磨琢磨

总有那身价贱的人给作业贴回复完整的代码
2012-12-02 09:41
罗庇鹏ksq
Rank: 5Rank: 5
来 自:太平洋
等 级:职业侠客
帖 子:220
专家分:310
注 册:2012-6-30
收藏
得分:0 
有时间再看看,神啊。

从来都是无所谓,现在也该学着有所谓。✿咱们一个人,别坐井观天❀
2012-12-02 22:46
suijishu
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:66
专家分:144
注 册:2012-12-1
收藏
得分:0 
膜拜大牛神作,可惜没分啊...
2012-12-02 22:57
TonyDeng
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
等 级:贵宾
威 望:304
帖 子:25859
专家分:48889
注 册:2011-6-22
收藏
得分:0 
把你挂到顶上,有没有动力接下去?

授人以渔,不授人以鱼。
2012-12-02 23:53
ytiantian_ha
Rank: 2
等 级:论坛游民
帖 子:29
专家分:19
注 册:2012-7-1
收藏
得分:0 
坚持看Z版
2012-12-03 09:46
wp231957
Rank: 20Rank: 20Rank: 20Rank: 20Rank: 20
来 自:神界
等 级:贵宾
威 望:423
帖 子:13688
专家分:53332
注 册:2012-10-18
收藏
得分:0 
以下是引用embed_xuel在2012-12-2 09:41:43的发言:

别人要问我指针,第一件事就是做这个
int a=10;
int *p = &a;
把p,*p,&p,a,&a,都打印出来琢磨琢磨
老大,我试着做了一下

/*
  别人要问我指针,第一件事就是做这个
  int a=10;
  int *p = &a;
  把p,*p,&p,a,&a,都打印出来琢磨琢磨
*/

int main()
{
    int a=10;
    int *p=&a;
    printf("p=%x\n",p);  //1、这个就是指向a的地址,数据应该和4一样
    printf("p=%x\n",&p); //2、这个貌似是变量p在内存中的地址,应该和4的地址相邻
    printf("p=%x\n",a);  //3、这个没问题,应该是0xa
    printf("p=%x\n",&a); //4、这个是a在内存中地址
    printf("p=%x\n",*p); //5、p是a在内存中地址,*p就是取值=0xa
    return 0;
}

DO IT YOURSELF !
2012-12-03 10:04
suijishu
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:66
专家分:144
注 册:2012-12-1
收藏
得分:0 
以下是引用wp231957在2012-12-3 10:04:24的发言:

老大,我试着做了一下

/*
  别人要问我指针,第一件事就是做这个
  int a=10;
  int *p = &a;
  把p,*p,&p,a,&a,都打印出来琢磨琢磨
*/

int main()
{
    int a=10;
    int *p=&a;
    printf("p=%x\n",p);  //1、这个就是指向a的地址,数据应该和4一样
    printf("p=%x\n",&p); //2、这个貌似是变量p在内存中的地址,应该和4的地址相邻
    printf("p=%x\n",a);  //3、这个没问题,应该是0xa
    printf("p=%x\n",&a); //4、这个是a在内存中地址
    printf("p=%x\n",*p); //5、p是a在内存中地址,*p就是取值=0xa
    return 0;
}
都是牛人!!!膜拜
2012-12-03 14:11
罗庇鹏ksq
Rank: 5Rank: 5
来 自:太平洋
等 级:职业侠客
帖 子:220
专家分:310
注 册:2012-6-30
收藏
得分:0 
void swap(int *pa, int *pb)
{
    int t = 0;
    t = *pa;
    *pa = *pb;
    *pb = t;
}
这个才是错的吧?版主是有目的的?

从来都是无所谓,现在也该学着有所谓。✿咱们一个人,别坐井观天❀
2012-12-03 16:20
快速回复:【新手向 大牛慎入】【瞎眼向】【内有指针妹子玉照】单纯的指针妹子和 ...
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015520 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved