首页 > 试题广场 >

对于下面的说法,正确的是____。

[单选题]
对于下面的说法,正确的是____。
  • 对于 struct X { short s; int i; char c; },sizeof(X) 的值等于 sizeof(s) + sizeof(i) + sizeof(c)
  • 对于某个double变量 a,可以使用 a == 0.0 来判断其是否为零
  • 初始化方式 char a[14] = "Hello, world!"; 和初始化方式 char a[14]; a = "Hello, world!"; 的效果相同
  • 在gcc编译器下,对于 int i = 3; printf("%d %d", ++i, ++i),运行输出为:4 5
  • 选项A、B、C、D中至少有两个是正确的
  • 以上选项均不正确
D选项,函数的参数是从右向左压栈的,输出时从栈顶开始,相当于: int i = 3;  ++i; ++i; printf("%d,%d",i,i);所以是 5,5;
再举一个例子,int i = 1; printf("%d,%d", i += 2, i *= 3); 在输出i之前先进行了i *= 3和 i += 2;最终i = 5;所以结果是5,5;
发表于 2016-07-26 09:54:54 回复(15)
XQ头像 XQ
选F
A结构体要按高位对齐,int占四个字节,short占两个,char占一个 字节,所以4+4+4=12;
B要判断一个双精度浮点数:if( abs(f) <= 1e-15 )
C数组初始化两种方式:一种逐个赋值 char a[14] ={‘H’,‘e’,'l','l','o'};另一种 char a[14] = "Hello, world!"
char a[14]; a = "Hello, world!";错误 a为数组首地址是常量不能改变
D 5,5

发表于 2015-09-04 10:58:41 回复(4)
6:        printf("%d,%d\n", ++i, ++i);
0040102F   mov         eax,dword ptr [ebp-4]
00401032   add         eax,1    //-------------->3+1 = 4
00401035   mov         dword ptr [ebp-4],eax
00401038   mov         ecx,dword ptr [ebp-4]
0040103B   push        ecx      //--------------->此时将i = 4压栈
0040103C   mov         edx,dword ptr [ebp-4]
0040103F   add         edx,1     //--------------->4+1 = 5
00401042   mov         dword ptr [ebp-4],edx
00401045   mov         eax,dword ptr [ebp-4]
00401048   push        eax      //--------------->此时将i= 5压栈
00401049   push        offset string "%d,%d\n" (0042401c)
0040104E   call        printf (004011a0)
00401053   add         esp,0Ch
先进后出原则-----------》输出4,5(vc6.0编译器)

	int i = 3;
00325BBE  mov         dword ptr [i],3  
	printf("%d,%d\n", ++i, ++i);
00325BC5  mov         eax,dword ptr [i]  
00325BC8  add         eax,1          //------------------>3+1 = 4
00325BCB  mov         dword ptr [i],eax  
00325BCE  mov         ecx,dword ptr [i]  
00325BD1  add         ecx,1          //------------------>4+1 = 5
00325BD4  mov         dword ptr [i],ecx  
00325BD7  mov         esi,esp  
00325BD9  mov         edx,dword ptr [i]  
00325BDC  push        edx            //----------------->将5压栈
00325BDD  mov         eax,dword ptr [i]  
00325BE0  push        eax            //----------------->将5压栈
00325BE1  push        32CC70h  
00325BE6  call        dword ptr ds:[3301ECh]  
00325BEC  add         esp,0Ch  
00325BEF  cmp         esi,esp  
00325BF1  call        __RTC_CheckEsp (032132Fh)  
先进后出原则-----------》输出5,5(vs2013编译器)
编辑于 2015-09-03 16:15:20 回复(4)

A选项考察C语言的内存对齐

内存对齐是一个比较常考察的一个部分。下面的分析都是基于32位机器考虑的。这里要注意两点:

  1. 所有的空间均需要为最大类型大小的整数倍
  2. 内存需要保持对齐

对于题目中的:

struct X { 
    short s; 
    int i; 
    char c; 
};

其中需要考虑变量s和c的对齐,很容易发现,应该是12。有一些编译器存在对该形式的优化,在实际分配内存的时候,会将该结构体按照如下的结构进行分配:

struct X { 
    short s; 
    char c; 
    int i;    
};

这样分配的内存会减少到8。

详细分析可以参考blog:http://blog.csdn.net/charles_r_chiu/article/details/47858885中的第26条

B选项考察double类型的比较

这一点应该是课本上的基本常识,是由于双精度丢失,所以只能够采用比较两个差绝对值是否小于一个很小的数字来确定。

C选项中,在标准库中,对于char数组是无法采用这种赋值方式进行赋值的。

D选项中,主要考察下面的内容

int main()
{

    int i = 1;
    printf("%d,%d\n", ++i, ++i);    //3,3
    printf("%d,%d\n", ++i, i++);    //5,3
    printf("%d,%d\n", i++, i++);    //6,5
    printf("%d,%d\n", i++, ++i);    //8,9
    system("pause");
    return 0;
}

首先是函数的入栈顺序从右向左入栈的,计算顺序也是从右往左计算的,不过都是计算完以后在进行的压栈操作:
对于第5行代码,首先执行++i,返回值是i,这时i的值是2,再次执行++i,返回值是i,得到i=3,将i压入栈中,此时i为3,也就是压入3,3;
对于第6行代码,首先执行i++,返回值是原来的i,也就是3,再执行++i,返回值是i,依次将3,5压入栈中得到输出结果
对于第7行代码,首先执行i++,返回值是5,再执行i++返回值是6,依次将5,6压入栈中得到输出结果
对于第8行代码,首先执行++i,返回i,此时i为8,再执行i++,返回值是8,此时i为9,依次将i,8也就是9,8压入栈中,得到输出结果。

但是这种操作是和编译器相关的,详细分析请参考的我的blog:http://blog.csdn.net/charles_r_chiu/article/details/47858885中第三条

编辑于 2017-09-10 19:06:23 回复(5)
对于A,编译器在编译程序时会遵循两条原则:一、结构体变量中成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍) 二、结构体大小必须是所有成员大小的整数倍。
所以s偏移量=0;i偏移量=s偏移量+s大小=2,但2不是int的整数倍,补2,得4;c偏移量=i偏移量+i大小=4+4=8,是char的整数倍;struct的大小=c偏移量+c大小=8+1=9,但不是所有成员大小的整数倍,补3,得12,满足。
发表于 2015-06-25 21:10:36 回复(3)
选F,对于A,sizeof(X)=2+2+4+1+3=12
    对于B,要判断一个双精度浮点数:if( abs(f) <= 1e-15 )
    对于C,第二种初始化方式是错误的,无法通过编译
    对于D,输出为5,5

发表于 2015-04-10 10:00:26 回复(14)
选F,
    对于A,sizeof(X)=4+4+4=12(内存对齐结构(或联合)的整体对齐规则:在数据成员完成各自对齐之后,结构(或联合)本身也要进行对齐)
    对于B,要判断一个双精度浮点数:if( abs(f) <= 1e-15 )
    对于C,第二种初始化方式是错误的,无法通过编译
    对于D,输出为5,4(从右向左)
发表于 2015-07-29 23:42:02 回复(3)
F 对于A选项由于结构体的对齐原因所以结构体大小不是单纯的成员长度和;对于B选项由于double类型存储的是近似值所以判断是否为0应该是判断是否位于一个小区间内,比如[-0.00001, 0.00001];C选项char a[14]; a = "Hello, world!"会出现编译错误;D选项的结果未定义;E错误;F正确
发表于 2015-04-10 09:48:15 回复(5)
D中输出为5,5的根本原因 是前置++返回值为引用,后置++返回的是值 测试一次 cout<<++i<<i++<<++i<<i++;大家就知道了。至于其他的上面说的都对,从后往前计算。保存在栈里。
发表于 2016-07-19 10:28:20 回复(2)
要判断一个单精度浮点数:则是if( abs(f) <= 1e-6);
要判断一个双精度浮点数:则是if( abs(f) <= 1e-15 );
发表于 2018-08-08 21:16:57 回复(0)
关于D选项:

(1)在运算过程中,先将对象进行递增修改,而后返回该对象(其实就是对象的引用)的叫前递增运算++a。在运算符重载函数中采用返回对象引用的方式编写。

(2)在运算过程中,先返回原有对象的值,而后进行对象递增运算的叫后递增运算a++。在运算符重载函数中采用值返回的方式编写,重载函数的内部实现必须创建一个用于临时存储原有对象值的对象,函数返回的时候就是返回该临时对象。

发表于 2016-09-08 20:56:39 回复(0)
--------我仅仅尝试着解释一下,为什么C语言函数参数是从右向左压栈的,以及为什么这样可以支持可变长参数。--------------------------------------------------------------------------------------
       C 程序栈底为高地址,栈顶为低地址,因此上面的实例可以说明函数参数入栈顺序的确是从右至左的。可到底为什么呢?查了一直些文献得知,参数入栈顺序是和具体 编译器实现相关的。比如,Pascal语言中参数就是从左到右入栈的,有些语言中还可以通过修饰符进行指定,如Visual C++。即然两种方式都可以,为什么C语言要选择从右至左呢?
进一步发现,Pascal语言不支持可变长参数,而C语言支持这种特色,正是这个原 因使得C语言函数参数入栈顺序为从右至左。具体原因为:C方式参数入栈顺序(从右至左)的好处就是可以动态变化参数个数。通过栈堆分析可知,自左向右的入 栈方式,最前面的参数被压在栈底。除非知道参数个数,否则是无法通过栈指针的相对位移求得最左边的参数。这样就变成了左边参数的个数不确定,正好和动态参 数个数的方向相反。
       因此,C语言函数参数采用自右向左的入栈顺序,主要原因是为了支持可变长参数形式。换句话说,如果不支持这个特色,C语言完全 和Pascal一样,采用自左向右的参数入栈方式。可变参数 主要通过第一个定参数来确定参数列表,所以从右至左入栈后,函数调用时pop出第一个参数就是 参数列表的第一个确定参数,就OK了……
       通俗点说,如果从左到右了,那栈顶的是最后一个参数,在使用的时候是要从第一个元素开始的,那又没有记录多少个参数的情况下,无法找到第一个参数,而从右到左就解决了这个问题,参数再多,只要栈空就可以判断参数都被用上了。
编辑于 2016-07-28 11:12:54 回复(1)
函数参数列表的入栈顺序为从右到左
发表于 2015-09-09 21:11:10 回复(0)
D选项结果不确定,gcc下测试为5 5
发表于 2015-04-10 23:03:41 回复(1)
这题目真的是,妙蛙种子吃着妙脆角妙进了米奇妙妙屋,妙到家了
发表于 2020-11-23 19:50:17 回复(0)
D选项,从右至左 输出5,5
发表于 2018-09-26 11:06:00 回复(0)
为什么B不对呢😨
发表于 2017-04-25 11:04:49 回复(1)
c中相当于直接把一个数组赋值给另一个数组
发表于 2017-03-27 17:04:24 回复(0)
D项,printf求值顺序是从右向左,输出是从左向右,所以是5 5
发表于 2015-07-07 18:34:49 回复(1)
数组名a是一个char * const类型,“hello world”类型是const char* 类型,类型不一致不能直接等。
发表于 2019-11-15 09:36:53 回复(0)