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<b&&x==y false(7)x=(int)y/b++ x为3.0(8)a--?++a:++a a为1(9)'a'+'\xa'+a 108(10)a=0,--a,a+=(a++)-a 表达式结果为-1,a的值为02.8 设i和j是int类型,a和b是double类型,下列表达式哪些是错误的,为什么?(1)a==b==c 错误,c未定义且逻辑错误(2)'a'^045 正确(3)7+i*--j/3 正确(4)39/-++i-+29%j 正确(5)a*++-b 错误,++需要左值(6)a||b^i 错误,^号左侧类型为double(7)i*j%a 错误,%右侧类型为double(8)i/j>>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<<y^mask>>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-18。
#include<stdio.h>int 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),并编写一个程序,根据用户输入的年份,输出该年各月的英文名及天数。
#include<stdio.h>enum 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; 试将下列表达式中隐含的类型转换改为用强制类型转换运算符转换的表达式。