2016.4.10 第一次测试选择题

来源:互联网 发布:大米护肤品怎么样知乎 编辑:程序博客网 时间:2024/05/16 09:14
1.有以下程序
#include <stdio. h>
int fun( intA )
{
    int b = 0;
    static int c = 3;
    a = ( c + +,b + + );
    return ( a );
}
main( )
{
    int a = 2,i,k;
    for( i = 0;i<2;i + + )
        k = fun( a + + );
    printf("%d\n",k );
}
程序的输出结果是?A(B)
A.4
B.0
C.1
D.2


注:
1.错误原因:这道题的正确案是B,而我当时选的A,原因是不了解逗号运算符。
2.新知识:在C语言中,多个表达式可以用逗号分开,其中用逗号分开的表达式的值分别结算,但整个表达式的值是最后一个表达式的值。
3.解析:因为b是在函数中定义的且初始化为0;所以不管传入的参数是多少,每次b都为0,根据都好运算符的运算规则,那么每次返回的a也为0,即k也为0.


2.有以下程序
#include <stdio.h>
main()
{
    int y = 1,x,a [ ] = {2,4,6,8,10},*p;
    p = &a[1];
    for (x = 0; x < 3;x + +)
     y = y + *(p + x);
    printf ("%d\n ",y );

程序运行后的输出结果是?B
A.17
B.19
C.18
D.20


注:
1.解析:p是一个整型的指针,指向数组的第二个元素,然后开始循环,可见,有三次循环,第一次x=0,则y=1+*p=1+4=5,第二次x=1;p指向第三个元素,y=5+*(p+1)=5+6=11,第三次x=2,p指向第四个元素,y=11+*(p+2)=11+8=19.选B。



3.以下程序的输出结果是:A(D)
#define M(x,y,z) x*y+z
main()
{
       int a=1, b=2, c=3;
       printf("%d/n",M(a+b,b+c,c+a));
}
A.19
B.17
C.15
D.12


注:
1.错误原因:宏定义运算没有掌握,先算了和再代入的表达式进行运算。
2.新知识:宏定义是替换,不做计算,也不做表达式求解。
格式一(字符串替换):#define标识符 字符串
格式二(参数替换):#define宏名(参数表) 字符串
例如:
#define S(r) r*r
area=S(a+b);第一步换为area=r*r;,第二步被换为area=a+b*a+b;
正确的宏定义是#define S(r) ((r)*(r))
格式三:#define STR(str) #str
#用于把宏定义中的参数两端加上字符串的""
例如:STR(my#name)会被替换成"my#name"
格式四:#define WIDE(str) L##str
则会将形参str的前面加上L(即将字符串替换成字符串)
比如:WIDE("abc")就会被替换成L"abc"
如果有#defineFUN(a,b) vo##a##b()
那么FUN(id ma,in)会被替换成void main()
①可以用#undef命令终止宏定义的作用域
②字符串( " " )中永远不包含宏
③宏定义不分配内存,变量定义分配内存。
④宏名和参数的括号间不能有空格
3.解析:根据宏定义的运算规则,则M(a+b,b+c,c+a)=a+b*b+c+c+a=1+2*2+3+3+1=12,选D


4.下面代码的输出结果是?D(C)
void main(void)
{
     int a[5]={1,2,3,4,5};
     int *ptr=(int *)(&a+1);
     printf("%d,%d",*(a+1),*(ptr-1));
}
A.1,2
B.2,4
C.2,5
D.出错

注:
1.错误原因:误解&a+1,以为访问到数组之外的空间去了
2.新知识:&a是取数组的首地址,+1,即相当于一个二维数组的行数增加1
3.解析:&a取数组首地址,即取到a[0]的 地址,然后在加1,即将这个数组看成二维数组,自身为第一行,原来的地址是a[0][0],加一后,地址变成了第二行的第一个,即相当于a[1][0],但这时第二行的空间还没有申请,我们只是知道他的地址而已,再用(int *)将这个地址的类型强制转化成int型,因为声明了一个int型的指针ptr来指向这个a[1][0]的地址,打印时,第一个*(a+1),即打印数组的第二个元素2,第二个,ptr本来指向第二行第一个,减一后就指向了第一行第五个了,再将这个地址中的数据打印出来,即数组中的第五个元素5.故选C


5.下述程序有什么问题?A(B)
#include   <string.h>
#include   <stdio.h>
#include   <stdlib.h>
void getmemory(char*p)  {   
    p=(char *) malloc(100);   
    strcpy(p,"hello world"); 

int main( )
{   
    char *str=NULL;   
    getmemory(str);   
    printf("%s\n",str);  
    free(str);   
    return 0;   
}
A.正常输出'hello world"
B.输出为空
C.输出"烫烫烫"
D.程序崩溃

注:1.错误原因:没有考虑到函数中的空间被用了会自动就释放了
2.解析:传进去的实参str只是一个指针,并没有分配空间,而在函数中,虽然为P分配了空间,但是当这个函数被调用完,所分配的空间也随之释放,所以str的指向仍然为空,输出即为空。选B


6.定义**a[3][4],则变量占用内存空间为()。B
A.4
B.48
C.192
D.12

注:
1.解析:**a[3][4]表示申请一个二维的指针数组,数组内存储的都是地址,一个地址即相当于一个int型数据,即这个二维数组中3*4=12个地址,就需要12*4=48的内存空间


7."My salary was increased by 15%!"B(D)
下列哪个选项可以准确的显示出上述语句?
A.printf("\"My salary was increased by 15/%\!\"\n");
B.printf("My salary was increased by 15%!\n");
C.printf("My salary was increased by 15'%'!\n");
D.printf("\"My salary was increased by 15%%!\"\n");

注:
1.错误原因:有些符号需要转义字符才能输出
2.新知识:
转义字符
意义
ASCII码值(十进制)
\a
响铃(BEL)
007
\b
退格(BS) ,将当前位置移到前一列
008
\f
换页(FF),将当前位置移到下页开头
012
\n
换行(LF) ,将当前位置移到下一行开头
010
\r
回车(CR) ,将当前位置移到本行开头
013
\t
水平制表(HT) (跳到下一个TAB位置)
009
\v
垂直制表(VT)
011
\\
代表一个反斜线字符''\'
092
\'
代表一个单引号(撇号)字符
039
\"
代表一个双引号字符
034
\?
代表一个问号
063

3.解析:两个%%输出一个%


8.(多项选择)请找出下面代码中的所有错误。说明:以下代码是把一个字符串倒序,如“abcd”倒序后变为“dcba”。B(ABCD)
1 #include "string.h"
2 int main()
3 {
4    char *src = "hello,world";
5    char *dest = NULL;
6    int len = strlen(src);
7    dest = (char *)malloc(len);
8    char *d = dest;
9    char *s = src[len];
10   while (len-- != 0)
11      d++ = s--;
12   printf("%s", dest);
13   return 0;
14  
15 }
A.第7行要为'\0'分配一个空间
B.第9行改成char * s = &src[len-1]
C.第12行前要加上*d = '\0'
D.第13行前要加上free(dest)释放空间


注:
1.错误原因:以为‘\0’会自动添加到字符串后面。
2.新知识:只有在用双引号为数组赋值字符串,并且字符串长度小于数组时,系统才会主动添加‘\0’,
3.解析:src[len],代表的数组中的具体数据而非地址,而且在这里len是数组的长度,这样表示已经数组越界了,需要将长度减一再访问。

3 0