C语言指针结构及共体类型扫盲题.docx
《C语言指针结构及共体类型扫盲题.docx》由会员分享,可在线阅读,更多相关《C语言指针结构及共体类型扫盲题.docx(12页珍藏版)》请在冰豆网上搜索。
![C语言指针结构及共体类型扫盲题.docx](https://file1.bdocx.com/fileroot1/2022-12/16/4e4a9ad3-b0ac-4cce-a138-188669442475/4e4a9ad3-b0ac-4cce-a138-1886694424751.gif)
C语言指针结构及共体类型扫盲题
本文说明(约定)及图例:
1.本文所涉及的变量(包括指针变量),若不加特别说明均以TurboC为参考基准。
(省得有人抬扛或引发激烈争吵),比如谈到int型就认为它有2字节,尽管有些系统的规定可能不一样。
并且stdio.h及conio.h这两个头文件会在程序中省略不写,若需运行程序请自行加上。
2.本文所涉及的指针类型只涉及普通指针及多层指针(指针的指针的…的指针),不考虑far指针和huge指针。
本文所涉及的地址,均为合理的假设值。
3.图例及说明
图例举例
在本文所表示的意义、说明
一个占4个字节的空间(一小格代表一个字节)
一个占4字节的结构体空间,这个结构体包括两个域,每个域2字节
一个占100字节的空间
一片空间,长度不定,存的是函数fun()的代码
一个占4字节的结构体,有两个a和b字段(域),a占2字节,b占2字节
一个变量P,长度4字节,存的数据是0x123400FF
*为了简化问题,除非特别说明,否则就不考虑机器放数据的先后顺序,而是照人类习惯
一个变量P,长度4字节,但里面存的数据不确定(随机值)
一个变量P,长度4字节,起始地址0x001234,P是个指针变量,存的是地址0x1234,这个地址指向另一片4字节的空间,空间对应的变量是X,空间首地址(也是X的首地址)0x1234FF,但空间的内容不确定。
(文字有点长,结合图来看看吧)
这个图示可以对应这两句:
longX;long*P=&X;
这个跟上面的类似,不过,P指向的不再是整个X,而是指向了X的前两个字节(当然首地址也是0x1234FF)。
这个图示可以对应这两句:
longX;int*P=(int*)&X;(前提:
int为2字节)
请一定一定要
先看前面的“本文说明”
再看题目!
!
!
!
题目在下一页开始…
题01.下面是段程序的代码及输出结果:
程序代码
输出
intmain(){
char*cp;int*ip;
short*sp;long*lp;
float*fp;double*dp;
void*vp;FILE*Fp;
printf("%d\t%d\n",sizeof(cp),sizeof(ip));
printf("%d\t%d\n",sizeof(sp),sizeof(lp));
printf("%d\t%d\n",sizeof(fp),sizeof(dp));
printf("%d\t%d\n",sizeof(vp),sizeof(Fp));
getch();
return0;
}
根据上述,其中sizeof()是一个测量变量长度的函数,则以下说法有哪些正确?
A.程序代码中所列举的几种指针变量的长度均一样
B.程序代码中所列举的几种指针变量的长度碰巧一样
C.这个程序的变量未初始化所以里面的值是随机值,程序输出不具备参考价值
题02.指针表示的是一个变量的首地址,也就是数据从哪里开始存放。
那么,假如上题中的A项是正确的,声明指针时,比如char*cp;这一句中,里面的char类型有什么用?
A.没作用,只不过是让程序员记住这个指针指向的是个char
B.因为指针表示的是首地址,所以系统通过声明语句的char类型来确定要读(写)的数据长度。
C.不知道有什么用,这样写是因为书上的语法要求这样写。
题03.计算机在存取数据时,若存取对象是多字节的则优先存取低字节。
(备注:
这一点其实我们一般不用知道也可以,因为系统帮我们完成了。
但由于本文讨论指针时如果不知道这一点,对某些结果可能想破脑子也想不到。
)先看一段程序及其输出:
intmain(){
intx=0x1234,k0,k1;
char*p=(char*)&x;
/*到这里,不用再讲这是什么意思了吧?
*/
k0=p[0];k1=p[1];
printf("%x%x\n",k0,k1);
printf("%X%X\n",&p[0],&p[1]);
/*这句是打出x的每个字节的地址*/
getch();
return0;
}
对于输出的第一行,也许你会好奇为什么输出的是3412而不是1234,这就表明一个事实,也就是上面提到的一点:
优无存取低字节。
再看看第二行的地址,会发现,变量x的值0x1234中的低字节0x34确实存在了低地址0xFFCA中(高字节那一半0x12存在了0xFFCB。
有关这个程序及输出的图,如下(只画出重要的):
如果你已经懂了,那么请问:
问题3.1.以下这个程序的输出结果是?
intmain(){
chars[]={0x11,0x22,0x33,0x44};
long*ip=(long*)s;
printf("%lx",*ip);
getch();
return0;
}
A.11223344B.22114433C.33441122D.44332211
问题3.2.下面的程序的输出结果又是什么呢?
intmain(){
chars[]={0x11,0x22,0x33,0x44};
int*ip=(int*)s;
printf("%x",*ip);
getch();
return0;
}
A.1122B.2211C.不知道D.都不是
题04.下面是段程序的代码及输出结果(注:
本题只有做完第03题才能做):
#defineSHOWVARS{\
printf("Y=%lX\n",Y);\
printf("cp=%X\t",cp);\
printf("ip=%X\n",ip);\
}
/*上面只是把3个printf语句的复合语句定义成一个宏;所以每一行末尾的\号不要去掉*/
/*上面这个宏的作用是回显三个变量的值*/
intmain(){
longY=0x12345678;char*cp=(char*)&Y;
int*ip=(int*)&Y;
SHOWVARS
printf("*(++cp)=0xBB\n",Y);
/*这个printf用来标记执行了什么语句*/
*(++cp)=0xBB;SHOWVARS
printf("*(++ip)=0xCCFF\n",Y);
*(++ip)=0xCCFF;SHOWVARS
getch();
return0;
}
根据上述代码及输出,下面关于指针ip的移动(即表达式++ip),以下图示正确的是:
选项
移动后
A
B
C
D
题05.下列有四个图示:
设N是一个整数,则:
符合定义ints[N];的结构是:
________
符合定义int*s[N];的结构是:
________
符合定义int**s[N];的结构是:
________
符合定义int***s;的结构是:
________
符合定义int(*s)[N];的结构是:
________
题06.假设一串字符串"abcd"在C语言代码中被编译时分配在内存的0x1234中。
下面给定两个图(强调:
在这里,按本文开始的约定,不关心数据的存储顺序!
):
那么关于下面两个定义:
char*s="abcd";charp[]="abcd";的说法正确的是:
A.s与p的结构都相同并且都是图1的结构
B.s与p的结构都相同并且都是图2的结构
C.s属于图1的结构,而p属于图2的结构
D.s属于图2的结构,而p属于图1的结构
题07.设有定义chararr[][N]={"i","am","very","handsome"};
问题07-1:
在上面的定义中,你认为N的值至少是整数____
A.无限制B.1C.2D.3E.8F.9
问题07-2:
请问arr[1]是什么东西?
A.不确定
B.字符a和m还有N-2个\0
C.一个地址,从这个地址开始依次存放着字符a,m以及N-2个\0
问题07-3:
下面几组语句中,能输出字符r的是?
(多项选择)
A.charc;c=*arr[2];printf("%c",c);
B.charc;c=arr[2][2];printf("%c",c);
C.char(*p)[N]=arr;p+=2;printf("%c",p[2]);
D.char(*p)[N]=arr;p+=2;printf("%c",((char*)p)[2]);\
注:
要是上面的D项你看不懂,请回头把前面的内容重新看一次,特别是有强制转换运算的,把代码和图看一下。
题08.下面是一个很简单的程序段,用来比较两个字符串:
chars1[]="abc",s2[]="abc";
intc=(s1==s2);printf("%d",c);
可是事实上,这段程序段的输出是0(也就是c为0)而不是预期的1(或-1).为什么?
A.人品问题
B.编译器问题
C.编译器的bug
D.虽然内容都为abc但存放的起始地址不同,所以s1,s2当然不可能相等,程序输出没问题!
题09.根据下面的代码及运行输出,选出正确的一项:
代码及输出-A
代码及输出-B
intmain(){
structabc{
inta;
longb;
charc[8];
}x;
/*测量结构体的长度*/
printf("%d\n",sizeof(structabc));
/*各成员起始地址*/
printf("%X%X%X\n",&x.a,&x.b,x.c);
getch();
return0;
}
注:
这是TC下的运行结果,没有内存对齐
intmain(){
unionabc{
inta;
longb;
charc[8];
}x;
/*测量共体的长度*/
printf("%d\n",sizeof(unionabc));
/*各成员起始地址*/
printf("%X%X%X\n",&x.a,&x.b,x.c);
getch();
return0;
}
现给出两个结构体:
根据上述,对于abc和def这两种结构:
A.两种结构都一样且都是A图所示结构
B.两种结构都一样且都是B图所示结构
C.abc为A图所示而def为B图所示
D.abc为B图所示而def为A图所示
题10.下面是一段简单的程序,作用是给结构体的一个字段赋字符串。
试试把正确的一项代码填在横线上(即[1]处)。
代码中的fflush(stdin);是清除键盘缓冲区,不在本文讨论范围内,只要看懂前面的scanf()即可,有兴趣的自已去baidu查,或者等你做对本题后把它去掉,对比程序有什么变化。
程序
所期望的输入与输出
structperson{
char*name;
intage;
}p;
intmain(){
chars[255]={0};
/*输入年龄*/
scanf("%d",&p.age);
fflush(stdin);
/*输入姓名*/
_______[1]______________
/*检查是否你输入的*/
printf("--ECHO--\n");
printf("%d%s",p.age,p.name);
getch();
return0;
}
供选择的答案
A.gets(p.name);
B.gets(s);p.name=s;
注1:
你选的答案正确与否,可以自已运行
注2:
如果你选错了答案,很正常,因为很多初学者都有犯这个错误。
题11.与上题差不多,下面是一段简单的程序,作用是给结构体的一个字段赋字符串。
试试把正确的一项代码填在横线上(即[1]处)。
代码中的fflush(stdin);是清除键盘缓冲区,不在本文讨论范围内,只要看懂前面的scanf()即可,有兴趣的自已去baidu查,或者等你做对本题后把它去掉,对比程序有什么变化。
程序
所期望的输入与输出
structperson{
charname[255];
intage;
}p;
intmain(){
chars[255]={0};
/*输入年龄*/
scanf("%d",&p.age);
fflush(stdin);
/*输入姓名*/
_______[1]______________
/*检查是否你输入的*/
printf("--ECHO--\n");
printf("%d%s",p.age,p.name);
getch();
return0;
}
供选择的答案
A.gets(p.name);
B.gets(s);p.name=s;
注1:
你选的答案正确与否,可以自已运行
注2:
如果你选错了答案,很正常,因为很多初学者都有犯这个错误。
本文完
附言:
其实以上都是以前我学习指针和结构体时产生过的疑问,只不过我自已是通过写程序来把这些问题解决了的,也就是说,与其说是题目,还不如是我的一种心得总结,只不过是以题目的形式放出来,同时也让看这篇文章的初学者有一个自已思考的机会。
至于说题目的答案就不给了,因为题目的答案就在题目之中,或是四个备选答案中(都是选择题!
估计这些答案,不管正确与否,都能给你一点启示)
说太长了,简单地说,也就两个重点:
第一,我解决了上面的几个问题(虽是自已想出的问题)后,指针我就算过关了,并可以解决几乎所有的指针问题(高手级别的就算了,不过我还没遇到过~~);第二,不要找我要答案。
2010.7.5
2010.07.2217:
16修正了“本文说明(约定)”中的两个错误图示