2.1 下列哪些是词法记号?关键字(是)注释空白符八进制常量(是)三字符序列字符串常量(是)括号(是)2.2 C编译器可将下列每一个源字符串分解为哪些记号?(不必考虑记号组合是否合法)(1) x+++y x, ++, +, y(2) -0xabL -, 0xabL(3) 2.89E+12L 2.89E+12L(4) "String+\"FOO\"" " String+ \"FOO\""(5) x**2 x, *, *, 2(6) "X??/" "X??/"(7) a?b a, ?, b(8) x--+=y x, --, +=, y(9) intx=+10 intx, =, +, 10(10) "String""FOO" "String", "FOO"(这道题当时改的时候有几个小题改得有错误,注意!)2.3 下列哪些不是标识符,为什么?标识符由字母、数字和下划线组成,但首字符必须是字母或下划线4th 不是,以数字开头;sizeof 不是(标准C的关键字)_limit 是_is2 是xYshould 是x*y 不是,* 非法o_no_o_no 是temp-2 不是,- 非法isn't 不是,' 非法enum 不是(标准C的关键字。
注:关键字也称为保留字,是被系统赋予特定含义并有专门用途的标识符关键字不能作为普通标识符,但可以作为宏名所有预处理均发生在识别这些关键字之前)2.4 在下列表示中,哪些是合法常数,哪些是非法常数?对于合法常数,指出其类型;对于非法常数,说明其错误原因2L 合法,long长整型''' 不合法,单引号组中的单引号前需要转义字符.12 合法,double双精度浮点型0x1ag 不合法,g不是16进制数中的符号,也不表示任何类型33333 合法,int整形"a" 合法,字符串常量"" 合法,字符串常量0. L 合法,long double长双精度浮点型E20 不合法,缺少尾数部分0377UL 合法,unsigned long无符号长整型'\18' 不合法,存在非8进制位'\0xa' 不合法,不符合十六进制字符码表示规则\xhh0x9cfU 合法,unsigned int无符号整形'\45' 合法,char字符型1. E-5 合法,double双精度浮点型'\0' 合法,char字符型3. F 合法,float浮点型"3'4"" 不合法,缺少转义符'"' 合法,char字符型(P35,双引号作为字符常量时既可用图形符号也可用转义序列表示)'\a' 合法,char字符型2.6 以下的变量声明语句中有什么错误?(1) int a; b = 5; 第一个分号改为逗号 int a, b=5;(2) doubel h; 关键字错误 double h;(3) int x = 2.3; 类型错误 float x = 2.3;(4) const long y; 需要赋初值 const long y = 0;(5) float a = 2.5*g; g未定义变量 int g = 1; float a = 2.5*g;(6) int a = b = 2; b未定义变量 int a = 2, b = 2;2.7 设变量说明为:int a = 1, b = 2, c = 3, d;double x = 2.0; y = 7.7;请给出下列表达式的值。
1) ++a*b-- 4(2) !a+b/c 0(3) a==-b+c true(4) d=a++,a*=b+1 d为1, a为6(5) d=y+=1/x y为8.2, d为8(6) a>2 正确(9) a+=i+=1+2 正确(10) int(a+b) 正确,VC++下可运行2.9 下面代码的执行结果是什么?char a = 1, b = 2, c = 3;printf("%d,%d,%d,%d\n",sizeof(c), sizeof('a'), sizeof(c='a'), sizeof(a+b+7.7));结果:1,4,1,82.10 设变量说明为:unsigned short x = 1, y = 2, z = 4, mask = 0xc3, w;short v;请给出下列表达式的值。
1) ~x&x 0(2) v=~x -2(3) w=~x^x 65535(4) x|y&x|z 5(5) w=y|z,(w<<3)+(w<<1) 60(6) w=x|y&x|z<>x 113(7) v=-1,v<<=1 -2(8) v=~x|x -1(9) w=x^~y 65532(10) x|y|z>>2 32.11写一个表达式,将整数k的高字节作为结果的低字节,整数p的低字节作为结果的高字节,拼成一个新的整数表达式为:32位k <<24 | (k & 255<<8)<<8 | (p & 255<<16)>>8 | p >>2416位(k >>8) | (p <<8)2.12 写一个表达式,将整数x向右循环移位n位表达式为:32位x<<(32-(n%32)) | x>>(n%32)16位x<<(16-(n%16)) | x>>(n%16)2.13 写一个表达式,将整数x从第p位开始的向右n位(p从右至左编号为0~15)翻转(即1变0,0变1),其余各位保持不变表达式为:x^((~0)<<(p+1-n) & ((unsigned short)~0)>>(16-p-1))或:x^(~0>>(16-n)<<(p+1-n))2.15 表达式v &= (v-1)能实现将v最低位的1翻转。
比如v=108,其二进制表示为01101100,则v &= (v-1)的结果是01101000用这一方法,可以实现快速统计v的二进制中1的位数,只要不停地翻转v的二进制数的最低位的1,直到v等于0即可请用该方法重写例2-18includeint main(void){unsigned char data, backup, t = 0;int parity = 0;data = getchar();backup = data;while(data){t++;data &= (data -1);}data = backup | ((parity<<7)^(t<<7));printf("The data is %#x\n", backup);printf("Parity-Check Code is %#x\n", data);return 0;}2.16写一个表达式,其结果是a、b和c这3个数中最大的一个表达式为:a>b?a>c?a:c:b>c?b:c 或(a>b)?(a>c?a:c):(b>c?b:c) 或(a>b)?((a>c)?a:c):((b>c)?b:c)2.18 写一个表达式,如果整数a能被3整除且个位数字是5,则结果为非0,否则为0。
表达式为:a%3 ? 0 : (a%10==5 ? 1 : 0)2.19 定义一个枚举类型enum month,用来描述一年12个月:一月(jan)、二月(feb)、……、十二月(dec),并编写一个程序,根据用户输入的年份,输出该年各月的英文名及天数includeenum year { jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec};int main(void){ enum yaer month; int year_num, year_days=365; char *month_name[] ={"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};int month_days[] = {31,28,31,30,31,30,31,31,30,31,30,31}; scanf("%d", &year_num);if(!(year_num%4) && year_num%100 || !(year_num%400))month_days[1]=29, year_days=366; printf("\n%d\n", year_days); for(month=jan; month <= dec; month++) printf("%s,%d\n", month_name[month],month_days[month]); return 0;}2.20 设变量说明为:float a; double b; char c; int x; 试将下列表达式中隐含的类型转换改为用强制类型转换运算符转换的表达式。
1) x = (int)(a - (float)(int)c + a)(2) b * (double)x + (double)( (int)c - (int)'0' )(3) ( x > 0 ) ? (double)a : b。