1.void main()
{int a=2,b=5;
printf("a=%%d,b=%%d\n");
}
结果为:()
A. a=%2,b=%5 B. a=2,b=5
C. a=%%d,b=%%d D. a=%d,b=%d
答案:D
2.若有说明:int n=2,*p=&n,*q=p,则以下非法的赋值语句是( )
A)p=q B)*p=*q C)n=*q D)p=n
答案:D
3.下面表达式不能访问二维数组b的第i行第j列元素的是()
A. b[i][j] B. *(b[i]+j)
C. *(*b+i)+j) D. (*(b+i))[j]
答案:C
【解析】:数组名 b 在表达式中也会被转换为指针。
- A选项b[i][j]:通过下标的方式,所以A正确。
- B选项*(b[i]+j) :b[i]相当于二维数组的i行,加上j,就相当于i行j列,然后取地址。所以B正确。
- C选项*(*b+i)+j):数组名b相当于指针,*b+i为b[0][i],取地址加j相当于b[j][i]。所以C错误。
- D选项(*(b+i))[j]:b+i为第i行地址,在使用*表示第i行首元素内容合并[j]下标,即b[i][j],所以D正确。
4.按C语言的规定,以下不正确的说法是 。
A)实参可以是常量、变量或表达式 B)形参可以是常量、变量或表达式
C)实参可以为任意类型 D)形参应与其对应的实参类型一致
答案:B
【解析】:形参不能是表达式
5.要使a的低四位翻转,需要进行操作是()
A. a|0xF B. a&0xF C. a^0xF D. ~a
答案:C
【解析】:0x开头为16进制,0xf对应的二进制数为1111。
^为异或操作,若参加运算的两个二进制位值相同则为0,否则为1;
a与0xf做异或操作,可以实现低四位的翻转。
如果是| 按位或 ,则将低四位数全变成1.
如果是& 按位与,则结果不变。
其他的位运算符号:
& 按位与 如果两个相应的二进制位都为1,则该位的结果值为1,否则为0
| 按位或 两个相应的二进制位中只要有一个为1,该位的结果值为1
^ 按位异或 若参加运算的两个二进制位值相同则为0,否则为1
~ 取反 ~是一元运算符,用来对一个二进制数按位取反,即将0变1,将1变0
<< 左移 用来将一个数的各二进制位全部左移N位,右补0
>> 右移 将一个数的各二进制位右移N位,移到右端的低位被舍弃,对于无符号数,高位补0
6.设“char s[10];*p=s”以下不正确的表达式是()
A.p=s+5; B.s=p+s; C.s[2]=p[4]; D.*(p+1)=s[0];
答案:B
【解析】:因为s是数组名,只代表数组的首地址,数组名也被成为指针变量,其值是不可改变的。所以不能给s赋其他值。
7.关于结构类型下面说法错误的是()
A. 结构类型不可作为其成员的类型
B. 结构变量的大小就是其各成员的大小之和
C. 结构类型可以定义在函数之外
D. 结构类型可以定义在函数之中
答案:B
【解析】:tag 是结构体标签。
member-list 是标准的变量定义,比如 int i; 或者 float f,或者其他有效的变量定义。
variable-list 结构变量,定义在结构的末尾,最后一个分号之前,您可以指定一个或多个结构变量。
struct tag { member-listmember-list member-list ...
} variable-list ;
结构类型无法将自己的类型作为其成员的类型,因为自己的类型定义尚不完整,要在结束的大括号(})后才算定义完整。所以A正确。
基于内存的对齐原则,一个结构体变量定义完之后,其在内存中的存储并不等于其所包含元素的宽度之和。从结构体存储的首地址开始,每一个元素放置到内存中时,它都会认为内存是以它自己的大小来划分的,因此元素放置的位置一定会在自己宽度的整数倍上开始(以结构体变量首地址为0计算),所以B错误。
结构类型和其他基本类型或数组类型类似的用法,可以定义在函数之中或函数之外。所以C、D正确。
8.以下叙述中错误的是( )
A) 可以给指针变量赋一个整数作为地址值
B) 函数可以返回地址值
C) 改变函数形参的值,不会改变对应实参的值
D) 当在程序的开头包含头文件stdio.h时,可以给指针变量赋NULL
答案:A
【解析】:不能将一个整数直接赋给指针变量作为地址,所以A)是错误的。函数的返回值可以是地址,即指针。函数调用中形参值的变化不会传递给实参。
9.C语言中,设a=3,b=4,执行语句“printf("%d,%d",(a,b),(b,a));”的输出结果是()
A. 3,4
B. (3,4),(4,3)
C. 4,3
D. 不确定
答案:C
【解析】:4,3这个是逗号表达式的问题,
逗号表达式从左往右执行,最后显示最右边的那个。
即(a,b)相当于b,如果是
printf("%d,%d",(++a,++b),(++b,++a));
输出为6,5
10.设有如下的变量定义:
int i=8, k, a, b;
unsigned long w=5;
double x=1, 42, y=5.2;
则以下符合C语言语法的表达式是
A) a+=a-=(b=4)*(a=3) B) x%(-3);
C) a=a*3=2 D) y=float(i)
答案:A
【解析】:A项是赋值表达式和算术表达式的结合,符合C语言语法;B项中,’%’是模运算符,要求运算符两侧均为整数,x为double,显然错误;C项是赋值表达式,要求赋值运算符的左侧是变量,3=2部分显然错误;D项,强制类型转换运算符使用错误,应为y=(float)i
11.下列关于const和#define定义常量的区别,说法不正确的有()
A. define宏是在预处理阶段展开。const常量是编译运行阶段使用
B. 宏没有类型,不做任何类型检查,仅仅是展开。const常量有具体的类型,在编译阶段会执行类型检查
C. define宏仅仅是展开,有多少地方使用,就展开多少次,不会分配内存。const常量会在内存中分配(可以是堆中也可以是栈中)
D. const定义和#define定义的常量在程序运行过程中只有一份拷贝
答案:D
[解析]:A,正确,#define定义的宏是在预处理阶段进行替换的,const常量是在编译、运行阶段进行使用的。
注意是仅仅的字符串替换,并不会检查其合法性。
预处理阶段做了的任务:
1:将头文件中的内容(源文件之外的文件)插入到源文件中
2:进行了宏替换的过程(简单的字符串替换),定义和替换了由#define指令定义的符号
3:删除掉注释的过程,注释是不会带入到编译阶段
4:条件编译
B,正确,所有的宏替换只是简单的字符串替换,注意是字符串替换,所以并不会检查其合法性,而const定义的常量依然是内置类型等,所以会对其进行类型安全检查。
C,正确,宏定义在程序中使用了几次在预处理阶段就会被展开几次,并不会增加内存占用,但是宏定义每展开一次,代码的长度就要发生变化(所以有利必有弊啊!),而const常量也会为其分配内存(如果是动态申请空间肯定就是堆中了)。
D,错误,const定义的常量只有一次拷贝没毛病,而define定义的变量在内存中并没有拷贝,因为所有的预处理指令都在预处理时进行了替换。
12.运行下面程序时,从键盘输入字母H,则输出结果是_____.
#include <stdio.h>
void main( )
{ char ch;
ch=getchar( );
switch(ch)
{ case 'H':printf("Hello!\n");
case 'G':printf("Good morning!\n");
default:printf("Bye_Bye!\n");
}
}
A) Hello! B) Hello!
Good Morning!
C) Hello! D) Hello!
Good morning! Bye_Bye!
Bye_Bye!
答案:C
13.设有定义:char p[]={‘1’, ‘2’, ‘3’},*q=p; ,以下不能计算出一个char型数据所占字节数的表达式是( )
A) sizeof(p)
B) sizeof(char)
C) sizeof(*q)
D) sizeof(p[0])
答案:A
【解析】根据题目中的定义可以知道sizeof(p),计算的是数组p中所有元素所占用的字节数,而不是char型数据所占字节数。
14.下面代码的输出结果是?
#include <stdio.h>
int main() {
int z, x = 5, y = -10, a = 4, b = 2;
z = x++ - --y * b / a;
printf("%d\n", z);
return 0;
}
A. 5
B. 6
C. 10
D. 11
E. 12
答案:C
int z, x = 5, y = -10, a = 4, b = 2;
z = x++ - --y * b / a;
step1.首先计算自增自减运算符,先计算 x++ 和 --y。
x++ :先使用x再对x进行++ ——>5
--y :先对y--再使用y的值 ——>-11
step2. “ * ”、“ / ”位于优先级第三级,“ - ” 位于优先级第四级,所以先进行乘除运算,算术运算符采取左结合,因此自左向右计算。
--y * b / a;
-11 * 2 / 4; -22/4 == -5.5
但是由于采用“ / ",所以会趋零截断得到 -5
(--y * b / a )== -5
step3.最后计算 “ - ”,采用左结合,自左向右计算。
先对x进行减法运算,再对x进行++
z = x++ - (--y * b / a);
z = 5 -(-5)= 10
计算完z = 10后,再对x进行++,最后x的值为6
15.在VC6.0中,运行下面程序的输出结果是()
#include <stdio.h>
#include <stdlib.h>
#include <string.h>void MallocMem(char* pc) {pc = (char*) malloc (100);return;
}int main() {char *str=NULL;MallocMem(str);strcpy(str,"hello ");strcat(str+2, "world");printf("%s",str);return 0;
}
A. hello world
B. 程序编译错误
C. 程序运行时崩溃
D. 其他几项都不对
答案:C
【解析】str还是指向NULL,并未给str分配空间,所以执行时会出现段错误。
16.对下面变量声明描述正确的有()
int *p[4];
int (*)p[4];
int *p();
int (*)p();
A. int *p[4];指针数组,每个元素均为指向整型数据的指针
B. int (*)p[4];p为指向一维数组的指针,这个一维数组有n个整型数据
C. int *p();函数带回指针,指针指向返回的值
D. int (*)p();—-p为指向函数的指针
答案:A
【解析】int *p[4]; //表示指针数组,有四个元素,每个元素都是整型指针。
int (*p)[4]; //表示行指针,所指对象一行有四个元素。
int *p(void); //表示函数,此函数无参,返回整型指针。
int(*P)(void) ;//表示函数指针,可以指向无参,且返回值为整型指针的函数。
17.以下选择中,正确的赋值语句是( )
A.a=1,b=2 B.j++
C.a=b=5; D.y=(int)x
答案:C
【解析】:选项A、B、D都无分号
变量 = 表达式;//赋值语句是一定带分号的
int a=b=c=5;//本语句错误
{
int a,b,c;
a = b = c = 5;
}//正确赋值语句
18.C语言中浮点类型数据不包括哪个部分()
A. 符号位 B. 指数位
C. 尾数部分 D. 小数
答案:D
【解析】:浮点数的存储:图片说明
S(1bit)符号位
E(8bit)指数位(-127~128)
M(23bit)有效数字 (1<= M <2)
float的值为(-1)^S*M*2^E
19.下面的程序可以从0....n-1中随机等概率的输出m个不重复的数。这里我们假设n远大于m
knuth(int n, int m)
{ srand((unsigned int)time(0)); for (int i = 0; i < n; i++) { if ( ) { printf("%d\n", i);( ); } }
}
A. rand()%(n-i) <= m m--
B. rand()%(n-i) < m m--
C. rand()%(n-i) >= m m++
D. rand()%(n-i) > m m++
答案:B
【解析】由这个for循环循环n次,且在满足条件时才输出i,可知,输出m个不同值的要求已满足,因为每次输出的都是i值,而i值每次都是不一样的,m--保证了程序在输出了m个值后就停止循环。
在i=0时,rand()%(n-i)的取值范围为0到n-1,共n个数,此时要输出0只需要rand()%(n-i)小于m,故i=0被输出的概率为m/n;
在i=1时,rand()%(n-i)的取值范围为0到n-2,共n-1个数,若i=0没有被输出,则m--未被执行,此时i=1被输出的概率为m/(n-1),若i=0已经被输出了,则m变为m-1,此时i=1被输出的概率为(m-1)/(n-1);由概率论的知识,可知此时i=1被输出的概率为
P=(1-m/n)*(m/(n-1))+m/n*((m-1)/(n-1))=m/n;以此类推,可知每个数被输出的概率都为m/n