跳转至

知识点 01 · 标识符、常量与数据类型

本页最后更新于 ,内容可能过时

1 · 标识符合法性

请选出可以作为 C 语言标识符的一组标识符。

  • A. total-sum, _value
  • B. count_, String
  • C. float, num#
  • D. 3data, while
答案

B

解析

逐项排雷——

  • A:total-sum 含减号 -,非法(合法连接符只有下划线);_value 本身合法。
  • B:count_ 以下划线结尾,合法;String 不是关键字(C 区分大小写,Stringstring)✅
  • C:float 是关键字;num##,非法。
  • D:3data 数字开头;while 是关键字,非法。

标识符四条铁律:① 只能由 字母、数字、下划线 _ 组成;② 不能以数字开头;

③ 不能是关键字(int/float/while/case/const/goto… 那 32 个);④ 区分大小写(INT 合法、int 非法)。

关键字"加料"后反而合法:_intint_int2 都是合法标识符——因为关键字必须整体匹配。

易错:以为 String 是关键字(那是 C++/Java 的 string),C 里没有 string 关键字。


2 · 标识符合法性

请选出可以作为 C 语言标识符的一组标识符。

  • A. 2num, f1, total
  • B. main, case, _sum
  • C. print, int$, number_1
  • D. _data, sum1, Average
答案

D

解析
  • A:2num 数字开头,非法(f1total 本身合法)。
  • B:case 是关键字,非法。(注意 main 是合法的——它是函数名,不是关键字;很多同学会误判。)
  • C:int$$,非法。
  • D:_datasum1Average 三个都合法。✅

易错:maindefineinclude 都不是关键字,是合法的普通标识符。真正不能用的是那 32 个关键字。


3 · 标识符合法性

请选出不可以作为 C 语言用户标识符的一组标识符。

  • A. A_1、Goto、Ba
  • B. character、_0、AbC
  • C. _a、__a、x_
  • D. temp、x#、INT
答案

D

解析

注意本题问的是"不可以"!

  • A:A_1 合法、Goto 合法(大小写敏感,Gotogoto)、Ba 合法 → 可以。
  • B:character_0AbC 全部合法(_0 下划线开头即可,后面跟数字没关系)→ 可以。
  • C:_a__ax_ 全部合法(下划线的位置和个数都不受限)→ 可以。
  • D:x## 非法 → 不可以。✅

易错:这题和上面两题问法相反("可以" vs "不可以"),读题时先把"可以/不可以"圈出来。


4 · 标识符合法性

以下是正确的 C 语言标识符是__。

  • A. int
  • B. in1_3
  • C. A_BID
  • D. const
答案

B(命题意图)

解析
  • A:int 是关键字,非法。
  • B:in1_3——字母开头、后面是数字与下划线,合法。✅
  • C:A_BID——也合法(全大写不会变成关键字,C 区分大小写,A_BID 只是一个普通标识符)。
  • D:const 是关键字,非法(const 从 C89 起就在关键字表里)。

说明

按标准 C 的规则,B 的 in1_3 和 C 的 A_BID 都是合法标识符,而材料上这一题给出的答案是 B。

这可能是原卷就这么出的(本题按单选设计),也可能是扫描时把某个选项改掉了字。

考场上按材料给的答案作答,选 B。

易错:① 以为 const 不是关键字;② 以为"全大写"是特殊写法——C 的大小写只影响"会不会撞上关键字",A_BIDINT 都完全合法。


5 · 标识符合法性

以下哪个变量名是无效的?

  • A. int_value
  • B. _tempVar
  • C. 2nd_var
  • D. totalSum
答案

C

解析

变量名 = 标识符,只能由字母、数字、下划线组成且不能以数字开头。

  • A:int_value 合法——int 只是它的前三个字母,不是关键字 int(关键字要整体匹配)。
  • B:_tempVar 下划线开头,合法。
  • C:2nd_var 以数字 2 开头,无效。❌
  • D:totalSum 合法(大小写混用没问题)。

易错:把 int_valueintValuefloat1 当成"用了关键字"——只要不是单独一个 int,就不算关键字。


6 · 标识符合法性

以下哪个是 C 语言中的合法标识符?

  • A. 123var
  • B. _var
  • C. var-name
  • D. var name
答案

B

解析
  • A:数字开头,非法。
  • B:_var 下划线开头,合法。✅
  • C:var-name 含减号 -,非法。
  • D:var name 含空格,非法。

易错:-(减号)和空格是两个最常出现的"看起来像连接符"的非法字符。合法连接符只有下划线 _


7 · 常量与转义字符

在下面给出的 C 语言常量表示中,错误的一项是( )。

  • A. '\x41'
  • B. 0x41
  • C. '\08'
  • D. "A"
答案

C

解析
  • A:\x41 是十六进制转义,41₁₆ = 65,即字符 'A',合法。
  • B:0x41 是十六进制整型常量,值也是 65,合法。
  • C:\0 是八进制转义,八进制只允许 07;后面的 8 不是八进制数字,于是 '\08' 变成两个字符的多字符常量——不是合法的常量表示(gcc 会警告 multi-character character constant,值还是实现定义的)。❌
  • D:"A" 是字符串字面量(占 2 字节:'A' + '\0'),合法。

必背转义序列表:

写法 含义 陷阱
\0 空字符(数值 0) 字符串结束标志;str['\0'] 就是 str[0]
\ddd 八进制转义,1–3 位 只认 07,遇到 8/9 立刻截断
\xhh 十六进制转义 \x 后可接任意多位的十六进制数字
\\ \' \" 反斜杠 / 单引号 / 双引号 \\ 是一个字符
\n \t \r \b 换行 / 制表 / 回车 / 退格

易错:把 '\08' 当成"合法的八进制转义"——它其实是这一题唯一的问题选项。


8 · 常量与转义字符

C 语言中,"\\xfds" 在内存中占用的字节数是( )。

  • A. 3
  • B. 4
  • C. 5
  • D. 6
答案

D(6 字节)

解析

数清楚到底有几个字符——

  • \\ 是一个字符(转义后的反斜杠 \);
  • 后面的 xfds 是 4 个普通字符(\x 这个引子已经被前面的 \\ 用掉了,不再构成转义)。

所以字符串里共 5 个字符,再加上自动追加的结束符 '\0' → 6 字节。✅

反例对照:若写成单个反斜杠 "\xfds",则 \xfd 会构成一个十六进制转义(fd 都是十六进制数字,读到 s 才停),串里只剩 \xfds 两个字符

→ 那时 sizeof 是 3 字节(strlen 是 2)。

分清三个"兄弟"(下表数值均由 gcc 15.2.0 实测):

写法 类型 占用
'A' int(字符常量) 4 字节
'\x41' int(十六进制转义,值 65) 4 字节
"A" char[2](字符串字面量) 2 字节

易错:① 把 \\ 当成两个字符(那会数成 7 字节);② 以为 \xfdfd 是两个字符;③ 忘了字符串末尾那个 '\0'


9 · 常量与转义字符

程序语句 printf("%d", strlen("hello\078world!")); 的输出结果是( )。

  • A. 13
  • B. 12
  • C. 6
  • D. 5
答案

A

解析

关键是 \078 怎么切。

  • \07 是八进制转义(7₈ = 7,一个不可打印字符),到此为止;
  • 后面剩下的 8 是普通字符 '8'

所以字符串实际内容是:h e l l o + \07 + 8 + w o r l d ! = 5 + 1 + 1 + 6 = 13 个字符(strlen 不数结尾的 '\0')。✅

易错:以为 \078 整体是一个转义字符(那样算出来是 12)。八进制转义遇到 8/9 就截断。

顺带分清:'\08' 错、"hello\078world!" 对 —— 差别在于单引号里 \0 后面直接跟了 8,一个引号里塞了两个字符,就成了多字符常量;

而字符串里 \07 + '8' 是两个独立的字符,完全合法。


10 · 常量与转义字符

设有说明:char c='\010'; int x=10; float y=1.2; 则表达式 (int)(1.0f*x-c+y/2) 的值是( )。

  • A. 1
  • B. 2
  • C. 3
  • D. 4
答案

B

解析

逐步算——

  1. '\010' 是八进制转义,10₈ = 8,所以 c = 8
  2. 1.0f * x = 1.0 * 10 = 10.0(float)
  3. 10.0 - cc 被提升为 10.0 - 8 = 2.0
  4. y / 2 = 1.2 / 2 = 0.6
  5. 2.0 + 0.6 = 2.6
  6. (int)2.6 = 2(截断,不是四舍五入)✅

易错:① 把 '\010' 当成十进制 10(八进制转义以 \0 开头,\010 = 8);② 以为 (int) 会四舍五入(C 的强制转换一律向零截断)。


11 · 常量与转义字符

请指出哪一个定义语句是正确的。

  • A. int 34x = 1234;
  • B. long a[] = {5L, 3L, -2L};
  • C. char b = 'Class';
  • D. double y = .45e-4.3L;
答案

B

解析
  • A:34x 以数字开头,不是合法标识符 → 定义非法。
  • B:5L3L-2L 是长整型常量(后缀 L 合法),数组省略长度、由初始化列表推出 long[3],合法。✅
  • C:'Class' 是多字符字符常量——不是"一个字符",值是实现定义的(gcc 15.2.0 警告:multi-character literal with 5 characters exceeds 'int' size),不能算"正确的定义"。
  • D:.45e-4.3L 的指数部分 -4.3 不是整数 —— 浮点常量的指数必须是整数,非法(.45 这种省略整数部分的写法本身是合法的,错的是指数)。

易错:① 忘了 L/UL/f 这些后缀是合法的(12345UL 也对);② 以为 'Class' 合法——它在 C 里语法上能过、值不保证,任何正规代码都不该写多字符常量。


12 · 常量与转义字符

以下哪种变量定义是无效的?

  • A. int *p = NULL;
  • B. char str[]="C Programming";
  • C. double rate = .05.3;
  • D. unsigned long id = 12345UL;
答案

C

解析

注意本题问"无效"的。

  • A:NULL 是空指针常量,int *p = NULL; 合法。
  • B:用字符串初始化字符数组,长度自动推出(char[14],含 '\0'),合法。
  • C:.05.3 里有两个小数点 → 不是合法的浮点常量(小数点只能出现一次),无效。❌
  • D:12345UL 的后缀 UL = unsigned long,合法。

易错:.05 这种"省略整数部分"的浮点常量本身是合法的,错的是后面第二个小数点。别把两者混为一谈。


13 · sizeof 的用法

若定义 int a[][2]={{1},{2},{3},4};sizeof(a) 的返回值为( )。

  • A. 48
  • B. 32
  • C. 16
  • D. 24
答案

B

解析
  1. 二维数组第一维可以省略,由初始化列表的行数推导。{{1},{2},{3},4} 有 4 个初始化元素(前 3 个是 {...},第 4 个是裸的 4,它会开启新的一行),所以 aint[4][2]
  2. 元素总个数 = 4 × 2 = 8 个 int
  3. sizeof(int) = 4 字节。
  4. sizeof(a) = 8 × 4 = 32。✅

行展开后是:

a[0] = {1, 0}
a[1] = {2, 0}
a[2] = {3, 0}
a[3] = {4, 0}

sizeof 核心记忆:sizeof(类型) = 类型占的字节数;sizeof(数组名) = 整个数组的字节数(不是元素个数!);

元素个数 = sizeof(a) / sizeof(a[0])sizeof 是运算符不是函数,编译期求值,sizeof(x++) 不会真的自增。

易错:把 4 也算进 a[0] 那一行(以为只有 3 行)。裸值会开启新的一行。


14 · sizeof 的用法

若定义 char a[][3]={'1','2','3','4'};sizeof(a) 的返回值为( )。

  • A. 4
  • B. 6
  • C. 8
  • D. 12
答案

B

解析

4 个初始化元素,每行 3 个 → 需要 2 行(3 + 1),所以 achar[2][3]

  • sizeof(a) = 2 × 3 × 1 = 6 字节。✅
  • 注意第 2 行只填了 '4',剩下 a[1][1]a[1][2] 被自动补 0。

易错:以为 4 个元素就占 4 字节。二维数组按整行分配,不足的补 0。

顺带:charsizeof 是 1,所以这里的 6 既是字节数也是元素个数——换成 int 就得再乘 4。


15 · 类型转换与整除

设有:int i = 3.0/2.0; double d = 3/2;id 的值分别为( )。

  • A. 1, 1.0
  • B. 2, 1.0
  • C. 1, 1.5
  • D. 2, 1.5
答案

A

解析

先算右边,后转换——

  • 3.0/2.0:两个都是 double → 结果是 double1.5;赋给 int i 时截断 → i = 1
  • 3/2:两个都是 int → 整数除法,结果就是 int1(余数 1 被丢弃);赋给 double dd = 1.0

关键:运算结果的类型由"参与运算的两个操作数的类型"决定,而不是由左边的变量决定。

易错:以为 double d = 3/2; 会得到 1.5。除法早就按 int 算完了,1.5 根本没出现过。

想得到 1.5 必须写 3.0/23/2.0(double)3/2


16 · 类型转换与整除

int n; float f=13.8; 则执行 n=(int)f%3; 后,n 的值是( )。

  • A. 1
  • B. 4
  • C. 4.333333
  • D. 执行报错
答案

A

解析
  1. (int)f13.8 截断得 13
  2. 13 % 313 = 4×3 + 1,余数 1;
  3. 赋给 nn = 1。✅

易错:% 的优先级高于 =,且 % 只能用于整型——所以必须先 (int) 转换。若写成 f%3(float 直接取模)那才是编译错误(选项 D)。


说明

  1. 第 4 题:选项 B(in1_3)与 C(A_BID)按 C 语言规则都合法,本题严格说没有唯一答案。答案按命题意图取 B,解析中已作说明。