1、选择题 1:设 float a=2, b=4, c=3;,以下 C 语言表达式与代数式 (a+b)+c 计算结果不一致的是 A.(a+b)*c/2 B.(1/2)*(a+b)*c C.(a+b)*c*1/2 D.c/2*(a+b) 参考答案:B,因为 a,b,c 三个变量都是浮点数,所以在 B 答案中其结果是 0,因为在计算 1/2是就是 0,如果改成 1/2.0 就正确了。2:为了向二进制文件尾部增加数据,打开文件的方式应采用 A.ab B.rb+ C.wb D.wb+ 参考答案:D3:下述程序执行后的输出结果是 include main() int x=f; printf(“%cn“,a+
2、(x-a+1); A.g B.hC.i D.j 参考答案:A4:C 语言中,下列运算符优先级最高的是 A.! B. C. D. 参考答案:A5:数组定义为“ int a 4 ; ”,表达式 ( ) 是错误的。 A.*a B.a 0 C.a D.a+ 参考答案:D6:执行语句“ k=71; ”后,变量 k 的当前值是 A.15 B.31 C.3 D.1 参考答案:C7:定义函数时,缺省函数的类型声明,则函数类型取缺省类型 A.void B.char C.float D.int 参考答案:D8:若 main()函数带参数,参数个数最多是 A.0 B.1 C.2 D.3 参考答案:C 只知道有定义形
3、式 main(int argc,char* argv))9:若有宏定义:#define MOD(x,y) xy则执行以下语句后的输出结果是int a=13,b=94;printf(dn, MOD(b,a+4) ; A.5 B.7 C.9 D.11 参考答案:B10:下列各个错误中,哪一个不属于编译错误 A.改变 x 原值 3 为 5 ,写作“ x=5 ;” B.花括号不配对 C.复合语句中的最后一条语句后未加分号 D.变量有引用、无定义 参考答案:A11:下列程序段运行后, x 的值是( ) a=1;b=2;x=0; if(!( - a)x - ; if(!b)x=7;else +x; A.0
4、 B.3 C.6 D.7 参考答案:A12:设#define N 3#define Y(n) (N+1)*n)则表达式 2*(N+Y(5+1)的值是 A.42 B.48 C.54 D.出错 参考答案:B Y(5+1) 传递过去的应该是 6,而不是简单的把 5+1 给替换掉13:若定义了 char ch=abc0def,*p=ch;则执行 printf(%c,*p+4);语句的输出结果是 A.def B.d C.e D.0 参考答案:C14:下列转义字符中错误的是 A.000 B.14 C.x111 D.2 参考答案:C error C2022: 273 : too big for charac
5、ter15:算术运算符,赋值运算符和关系运算符的运算优先级按从高到低依次为 A.算术运算、赋值运算、关系运算 B.算术运算、关系运算、赋值运算 C.关系运算、赋值运算、算术运算 D.关系运算、算术运算、赋值运算 参考答案:B16:设#define N 3 #define Y(n) (N+1)*n) 则表达式 2*(N+Y(5+1)的值是 A.42 B.48 C.54 D.出错 参考答案:B17:表达式 strcmp( “ 3.14 ”,“ 3.278 ” ) 的值是一个 A.非零整数 B.浮点数 C.0 D.字符 参考答案: A18:设 struct short a; char b; floa
6、t c; cs; 则 sizeof(cs)的值是 A.4 B.5 C.6 D.7 参考答案: D 字节对齐的话应该是 819:若变量已正确定义,表达式( j=3 , j+ )的值是 A.3 B.4 C.5 D.0 参考答案:A20:C 语言中运算对象必须是整型的运算符是 A.% B./ C.! D.* 参考答案:A简答题21:打印一个 N*N 的方阵,N 为每边字符的个数( 3N20 ),要求最外层为“X” ,第二层为“Y”,从第三层起每层依次打印数字 0,1,2,3,. 例子:当 N =5,打印出下面的图形: X X X X X X Y Y Y X X Y 0 Y X X Y Y Y X X
7、 X X X X 22:谈谈 COM 的线程模型。然后讨论进程内/外组件的差别。 23:多态类中的虚函数表是 Compile-Time,还是 Run-Time 时建立的? 参考答案: 虚拟函数表是在编译期就建立了,各个虚拟函数这时被组织成了一个虚拟函数的入口地址的数组 .而对象的隐藏成员-虚拟函数表指针是在运行期 -也就是构造函数被调用时进行初始化的 ,这是实现多态的关键.24:#include void main() int c; while (c=getchar()!= n ) switch(c - 2 ) case 0: case 1:putchar(c+4);break; case 2
8、:putchar(c+4);break; case 3:putchar(c+3);break; default:putchar(c+2);break; printf( n ); 运行时输入: 2473 ,输出结果: 参考答案:6897 VC+6.0 测试过25:用两个栈实现一个队列的功能? 参考答案:设 2 个栈为 A,B, 一开始均为空.入队: 将新元素 push 入栈 A;出队: (1)判断栈 B 是否为空; (2)如果不为空,则将栈 A 中所有元素依次 pop 出并 push 到栈 B; (3)将栈 B 的栈顶元素 pop 出;这样实现的队列入队和出队的平摊复杂度都还是 O(1), 26
9、:写一语句实现 x 是否为 2 的若干次幂的判断。 参考答案:!(X) 返回值:解的个数 28:如何判别一个数是 unsigned。 参考答案;#define issignal(x) (x=0 main() char *bp; for (bp=b;*bp;bp+=2) printf(“%s“,bp); printf(“n“); 30:已知一个数组 table,用一个宏定义,求出数据的元素个数。参考答案:#define NTBL#define NTBL (sizeof(table)/sizeof(table0)1.#define pi 3.14#define Area(R) pi*R*Rmain
10、()int r1=5,r2=2;double s=0;s=Area(r1-r2);printf(“The area is %f“,s);求结果: The area is 3.7000002.函数 int compare(int a,int b),定义为该函数的函数指针 P:为 int(*p)(int,int);p= compare;3.求输出结果#includevoid sub(char*s,int num)int i ,j=num;char t;while(j1)for(i=0;i5 4 3 2 1 ,补充程序#define N 10typedef struct Nodeint data;s
11、truct Node*next;NODE;int Get_Data(int i);/定义省略Node*Create_u()int i;NODE*p,*Head=NULL;for(i=0;iData=Get_Data(i);_;_;return Head;其实就是个头插法/7*/N 个结点链表,每个结点中存放一个字符 ,判断链表存放的字符是否/中心对称,即 a b c c b a 或 a b c b a,补充程序typedef struct Nodeint data;struct Node*next;NODE;bool Is_symmeic(NODE*head,*int n)char DN;in
12、t i,d;_;for(i=0;idata;head=head-next;if(_)head=head-next;while(head)_;if(Di!=head-data)return false;head=head-next;return true;/8*/str 中只含有大写和小写字母函数 change_move(char*str)将字符串中大写改成*并/移到前面小写后返回 *的个数/如 AabBdcYY 改为*abd,返回 5int chang_move(char*str)int len,i,curstr=-1;len=strlen(str);for(i=len-1;i=0;i-)if
13、(stri=Astri=*;_;return_;/9*/求两个字符串的第一个公共子串, 并返回该子串/如:“a b c d e f g e h i“ “a a c d e f * * g e h i“/第一个为“c d e f“;不许用 strcmp()char*Maxf(char*str1,char*str2)、将一个链表逆序 LinkList *reverse(LinkList *head)LinkList *p1,*p2 = NULL,*p3 = NULL;if(head = NULL | head-next = NULL)return head;p1 = head-next;while
14、(p1!=NULL)p3 = p1-next;p1-next = p2;p2 = p1;p1 = p3;head-next = p2;/ head = p2;return head; 2、计算一个字节里(byte)里面有多少 bit 被置 1 #include int comb(const int c)int count = 0;int i = 0;int cc = c;while(i+1;return count;int main()const int c = 0xcf;printf(“%dn“,comb(c);return 1;3、在一个字符串中找到可能的最长的子字符串 #include
15、#include #include char *commanstring(char shortstring,char longstring)int i,j;char *substring = malloc(256);if(strstr(longstring,shortstring)!=NULL)return shortstring;for(i=strlen(shortstring)-1;i0;i-)for(j=0;jstrlen(str2)comman= commanstring(str2,str1);elsecomman = commanstring(str1,str2);printf(“t
16、he longest comman string is:%sn“,comman);4、字符串转换为整数 #include #include void reverse(char s) /字符串反转int c, i=0, j;for(j=strlen(s)-1;i0);/如果是负数,补上负号if(sign#include int Atoi(char str)int i;int weight = 1; / 权重int rtn = 0; / 用作返回for(i = strlen(str) - 1; i = 0; i-)rtn += (stri - 0)* weight; /weight *= 10;
17、/ 增重return rtn;void main()char str32;printf(“Input a string :“);gets(str);printf(“%dn“, Atoi(str);6、将一个字符串逆序 #include #include char *strconv(char *p)int length = strlen(p);char *ptr = p;char *ptr_1 = p + length -1;while(ptr class Apublic:/ A() i=3; / 不注释掉会出现链接错误void foo() printf(“%dn“,i);private:sta
18、tic int i; /如果换成 static int i=10;出错;int A:i=10; /static 变量在类外定义void main()A a;a.foo();3.求函数返回值,输入 x=9999; int func ( x ) int countx = 0; while ( x ) countx +; x = x return countx; 结果呢? 知道了这是统计 9999 的二进制数值中有多少个 1 的函数,且有 999991024512256 15 91024 中含有 1 的个数为 2; 512 中含有 1 的个数为 1; 256 中含有 1 的个数为 1; 15 中含有
19、 1 的个数为 4; 故共有 1 的个数为 8,结果为 8。 1000 - 1 = 0111,正好是原数取反。这就是原理。 用这种方法来求 1 的个数是很效率很高的。 不必去一个一个地移位。循环次数最少。 4.分析下面的程序struct s1 int i: 8; int j: 4; int a: 3; double b; ; struct s2 int i: 8; int j: 4; double b; int a:3; ; printf(“sizeof(s1)= %dn“, sizeof(s1); printf(“sizeof(s2)= %dn“, sizeof(s2); result: 1
20、6, 24 第一个 struct s1 int i: 8; int j: 4; int a: 3; double b; ; 理论上是这样的,首先是 i 在相对 0 的位置,占 8 位一个字节,然后,j 就在相对一个字节的位置,由于一个位置的字节数是 4 位的倍数,因此不用对齐,就放在那里了,然后是 a,要在 3位的倍数关系的位置上,因此要移一位,在 15 位的位置上放下,目前总共是 18 位,折算过来是 2 字节 2 位的样子,由于 double 是 8 字节的,因此要在相对 0 要是 8 个字节的位置上放下,因此从 18 位开始到 8 个字节之间的位置被忽略,直接放在 8 字节的位置了,因此
21、,总共是 16字节。 1. 一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如: struct bs unsigned a:4 unsigned :0 /*空域*/ unsigned b:4 /*从下一单元开始存放 */ unsigned c:4 在这个位域定义中,a 占第一字节的 4 位,后 4 位填 0 表示不使用,b 从第二字节开始,占用4 位,c 占用 4 位。 2. 由于位域不允许跨两个字节,因此位域的长度不能大于一个字节的长度,也就是说不能超过8 位二进位3. 位域可以无位域名,这时
22、它只用来作填充或调整位置。无名的位域是不能使用的。例如: struct k int a:1 int :2 /*该 2 位不能使用*/ int b:3 int c:2 ; 从以上分析可以看出,位域在本质上就是一种结构类型, 不过其成员是按二进位分配的。 5.在对齐为 4 的情况下 分析下面程序的结果struct BBB long num; char *name; short int data; char ha; short ba5; *p; p=0x1000000; p+0x200=_; (Ulong)p+0x200=_; (char*)p+0x200=_; 解答:假设在 32 位 CPU 上,
23、 sizeof(long) = 4 bytes sizeof(char *) = 4 bytes sizeof(short int) = sizeof(short) = 2 bytes sizeof(char) = 1 bytes 由于是 4 字节对齐, sizeof(struct BBB) = sizeof(*p) = 4 + 4 + 2 + 1 + 1/*补齐*/ + 2*5 + 2/*补齐*/ = 24 bytes (经 Dev-C+验证) p=0x1000000; p+0x200=_; = 0x1000000 + 0x200*24 指针加法,加出来的是指针类型的字节长度的整倍数。就是
24、p 偏移 sizeof(p)*0x200.(Ulong)p+0x200=_; = 0x1000000 + 0x200 经过 ulong 后,这已经不再是指针加法,而变成一个数值加法了(char*)p+0x200=_; = 0x1000000 + 0x200*1 结果类型是 char*,这儿的 1 是 char 的数据类型是 1 字节6.分析一下下面程序的输出结果i ncludei nclude i nclude i nclude i nclude i nclude typedef struct AAint b1:5;int b2:2;AA;void main()AA aa;char cc100
25、;strcpy(cc,“0123456789abcdefghijklmnopqrstuvwxyz“);memcpy(cout int main(void) int *p;int arr100;p = return 0;答案:int *p; /二级指针/得到的是指向第一维为 100 的数组的指针应该这样写i nclude int main(void) int *p, *q;int arr100;q = arr;p = return 0;8.写一个内存拷贝函数,不用任何库函数.void* memcpy(void* pvTo, const void* pvFrom, size_t size)asse
26、rt(pvTo != NULL) byte* pbTo = pvTo;byte* pbFrom = pbFrom;while (size- 0)*pbTo+ = *pbFrom+;return pvTo;9.将一个数字字符串转换为数字.“1234“ 1234int convert(char* str)int k = 0;while (*str != 0)k = k * 10 + (*str+) - 0;return k; 10.写出运行结果#include #include #define STRCPY(a, b) strcpy(a#_p, #b)#define STRCPY1(a, b) s
27、trcpy(a#_p, b#_p)int main(void) char var1_p20;char var2_p30;strcpy(var1_p, “aaaa“);strcpy(var2_p, “bbbb“);STRCPY1(var1, var2);STRCPY(var2, var1);printf(“var1 = %sn“, var1_p);printf(“var2 = %sn“, var2_p);return 0;答案:var1 = bbbbvar2 = var1宏中“#“和“#“的用法一、一般用法我们使用#把宏参数变为一个字符串, 用#把两个宏参数贴合在一起.用法:#include#i
28、ncludeusing namespace std;#define STR(s) #s#define CONS(a,b) int(a#e#b)int main()printf(STR(vck); / 输出字符串“vck“printf(“%dn“, CONS(2,3); / 2e3 输出:2000return 0; 二、当宏参数是另一个宏的时候需要注意的是凡宏定义里有用#或#的地方宏参数是不会再展开.1, 非#和#的情况#define TOW (2)#define MUL(a,b) (a*b)printf(“%d*%d=%dn“, TOW, TOW, MUL(TOW,TOW);这行的宏会被展开为
29、:printf(“%d*%d=%dn“, (2), (2), (2)*(2);MUL 里的参数 TOW 会被展开为(2).2, 当有#或#的时候#define A (2)#define STR(s) #s#define CONS(a,b) int(a#e#b)printf(“int max: %sn“, STR(INT_MAX); / INT_MAX #include这行会被展开为:printf(“int max: %sn“, “INT_MAX“);printf(“%sn“, CONS(A, A); / compile error这一行则是:printf(“%sn“, int(AeA);A 不
30、会再被展开, 然而解决这个问题的方法很简单 . 加多一层中间转换宏.加这层宏的用意是把所有宏的参数在这层里全部展开, 那么在转换宏里的那一个宏 (_STR)就能得到正确的宏参数.#define A (2)#define _STR(s) #s#define STR(s) _STR(s) / 转换宏#define _CONS(a,b) int(a#e#b)#define CONS(a,b) _CONS(a,b) / 转换宏printf(“int max: %sn“, STR(INT_MAX); / INT_MAX,int 型的最大值,为一个变量 #include输出为: int max: 0x7f
31、ffffffSTR(INT_MAX) _STR(0x7fffffff) 然后再转换成字符串;printf(“%dn“, CONS(A, A);输出为:200CONS(A, A) _CONS(2), (2) int(2)e(2) 11:此题考查的是 C 的变长参数,就像标准函数库里 printf()那样.#includeint ripple ( int , .);main()int num;num = ripple ( 3, 5,7);printf( “ %d“ , num);int ripple (int n, .)int i , j;int k;va_list p;k= 0; j = 1;v
32、a_start( p , n);for (; jclass Apublic:/ A() i=3; / 不注释掉会出现链接错误void foo() printf(“%dn“,i);private:static int i; /如果换成 static int i=10;出错;int A:i=10; /static 变量在类外定义void main()A a;a.foo();3.求函数返回值,输入 x=9999; int func ( x ) int countx = 0; while ( x ) countx +; x = x return countx; 结果呢? 知道了这是统计 9999 的二进制数值中有多少个 1 的函数,且有 999991024512256 15 91024 中含有 1 的个数为 2; 512 中含有 1 的个数为 1; 256 中含有 1 的个数为 1; 15 中含有 1 的个数为 4; 故共有 1 的个数为 8,结果为 8。 1000 - 1 = 0111,正好是原数取反。这就是原理。 用这种方法来求 1 的个数是很效率很高的。 不必去一个一个地移位。循环次数最少。 4.分析下面的程序