程序设计理论复习
部分由大语言模型生成,请辨别信息真伪
易错
1.枚举类型不用等号定义
正例:
1 | enum a {one=9, two=-1, three} |
2.if-else对应关系
1 | int main(){ |
else是对应外面的if,是不会执行的,还有如果if没加括号只有下一句对应if,剩下对应全局a=8-2+5=11
3.常量字符串也是指针,也有地址
以下是对选项的分析:
A.
1 | char *c = "Hello world!"; |
- 分析:
- 这段代码定义了一个字符指针
c
,并将字符串字面量"Hello world!"
的地址赋值给c
。 - 字符串字面量在程序的只读数据区,
c
可以指向它,但不能修改其内容。
- 这段代码定义了一个字符指针
- 正确性:正确。
B.
1 | char *c; |
- 分析:
- 定义了一个字符指针
c
,然后将字符串字面量"Hello world!"
的地址赋值给c
。 - 和选项 A 的区别在于,这里分两步完成:先定义指针,再赋值。
- 指针
c
指向的字符串字面量仍在只读数据区,不能修改。
- 定义了一个字符指针
- 正确性:正确。
C.
1 | char *c; |
分析:
- 这里定义了一个字符指针
c
,但它没有指向任何有效的内存。 strcpy
试图将"Hello world!"
的内容复制到c
指向的地址,但由于c
未被初始化,可能指向随机内存地址,导致 未定义行为。
- 这里定义了一个字符指针
正确性:错误。
c
应该指向一个足够大的有效内存区域,比如:1
2
3char buffer[50];
char *c = buffer;
strcpy(c, "Hello world!");
D.
1 | char *c; |
- 分析:
- 这里的
*c
表示指针c
指向的地址所存储的内容。 - 但是指针
c
没有被初始化,*c = "Hello world!"
会尝试将字符串地址存储到一个未定义的内存位置,导致 未定义行为。 - 即使
c
被初始化,比如char *c = NULL;
,对*c
的解引用仍然是不合法的。
- 这里的
- 正确性:错误。
B 和 D 的区别
B.
c
被赋值为字符串字面量"Hello world!"
的地址,指针c
指向有效的字符串内存位置。- 这是合法的操作,且字符串内容存储在只读数据区。
D.
*c
解引用了指针c
,但指针c
未被初始化,解引用操作会导致 未定义行为。- 此外,直接将字符串地址赋值给
*c
也是错误的语法。
总结
- 正确的选项是 A 和 B。
- B 和 D 的区别:
- B 是合法操作,将字符串地址赋值给指针。
- D 是未定义行为,尝试解引用未初始化的指针,操作无效且错误。
4. =和== 的区别
以下程序段
1 | int k = 0; |
while
循环执行的次数是()
A.
执行一次
B.
一次也不执行
C.
无限次
D.
有语法错误,无法执行
应是无限次,赋值操作返回值是1
5.隐藏的自增自减
执行以下程序段后,变量a的值为()
1 | int a = 0; |
答案应该是5,不要忽略前面的 ++a
6.字符串函数操作是已经会改变值的
1 | int main(){ char str1[100]; char str2[100]; strcpy(str1,"saBaaG"); strcpy(str2,strlwr(str1)); printf("%s\n",str1); printf("%s\n",str2); return 0; } |
输出:
1 | sabaag |
而不是:
1 | saBaaG |
7.C语言程序入口
在默认情况下,C语言程序的入口一般是:
C. int main(int argc, char *argv[])
;
这是标准的C语言程序入口函数形式。它接受两个参数:
argc
:命令行参数的数量(包括程序名本身)。argv
:一个字符串数组,包含命令行参数。
虽然有其他写法,如 int main()
,但 int main(int argc, char *argv[])
是较为常见的形式,特别是在需要处理命令行参数时。
8.关键字
在C语言中,以下是关键字或保留字:
- A.
sizeof
: 这是一个关键字,用于获取数据类型或变量的大小。 - B.
return
: 这是一个关键字,用于从函数中返回一个值。 - C.
int
: 这是一个关键字,用于声明整型变量或函数返回类型。
而 D. main
不是关键字,它是C语言程序的入口函数名称,程序的执行从 main()
函数开始。但它并不是C语言的保留字。
更多关键字:
以下是C语言关键字列表,按照功能分类:
1. 数据类型相关的关键字
- **
char
**:字符类型 - **
int
**:整型 - **
float
**:浮点型 - **
double
**:双精度浮点型 - **
void
**:空类型 - **
signed
**:有符号类型 - **
unsigned
**:无符号类型 - **
short
**:短整型 - **
long
**:长整型 - **
const
**:常量类型 - **
volatile
**:易变类型 - **
restrict
**:限制指针类型(C99引入)
2. 控制结构相关的关键字
- **
if
**:条件语句 - **
else
**:条件语句的另一个分支 - **
switch
**:选择结构 - **
case
**:switch
语句的分支 - **
default
**:switch
语句的默认分支 - **
for
**:循环结构 - **
while
**:循环结构 - **
do
**:循环结构(至少执行一次) - **
break
**:跳出循环或switch
- **
continue
**:跳过当前循环的剩余部分,进入下一次循环 - **
goto
**:跳转到代码中的标签(不推荐使用)
3. 函数和作用域相关的关键字
- **
return
**:从函数中返回值 - **
sizeof
**:返回类型或变量的字节大小 - **
typedef
**:定义类型别名 - **
static
**:定义静态变量或函数(局部保持状态,避免函数外部可见) - **
extern
**:声明变量或函数在其他文件中定义 - **
inline
**:函数内联(C99引入)
4. 结构体和联合相关的关键字
- **
struct
**:结构体定义 - **
union
**:联合体定义 - **
enum
**:枚举类型定义
5. 程序控制和内存管理相关的关键字
- **
auto
**:自动变量(通常用于局部变量,但默认情况下不使用) - **
register
**:寄存器变量(建议编译器优化) - **
sizeof
**:计算对象的大小 - **
restrict
**:告诉编译器该指针是唯一指向对象的
这些关键字都有特定的含义和用途,并且不能用作标识符(例如,不能用作变量名或函数名)。
9.运算符
C. C语言内置的运算符包括:关系运算符、位置运算符、赋值运算符等、算术运算符等
- 部分正确,部分错误。C语言内置的运算符包括:
- 算术运算符:
+
,-
,*
,/
,%
- 关系运算符:
==
,!=
,<
,>
,<=
,>=
- 逻辑运算符:
&&
,||
,!
- 赋值运算符:
=
,+=
,-=
,*=
,/=
, 等等 - 位运算符:
&
,|
,^
,<<
,>>
- 其他如指针运算符(
*
,&
)和条件运算符(?:
)等 然而,位置运算符并不是C语言中标准的运算符,通常没有这样的分类。因此,这个说法是 错误的。
- 算术运算符:
D. 操作数类型隐式转换的过程也总是变量分配内存空间增大或减小的过程
- 错误。隐式类型转换并不总是导致内存空间的增大或减小。隐式转换可能会发生类型提升(例如,将
int
转换为float
)或类型降级(例如,将float
转换为int
),但这些转换并不一定会改变变量所占用的内存大小。例如,char
转换为int
时,内存可能会增大;而double
转换为float
时,内存可能会减小,但不是所有隐式转换都会引起内存分配的增减。
理论
在 C语言 中,变量根据不同的分类标准可以分为以下几种类型:
1. 按数据类型分类:
变量的类型决定了它存储的数据类型。C语言中的基本数据类型包括:
基本数据类型:
char
:字符类型,通常占 1字节。int
:整数类型,通常占 4字节(具体取决于平台)。float
:单精度浮点类型,通常占 4字节。double
:双精度浮点类型,通常占 8字节。long
:长整型。short
:短整型。
派生数据类型:
- 数组:如
int arr[10]
。 - 指针:如
int *p
。 - 结构体(struct):如
struct student
。 - 联合体(union):如
union data
。 - 枚举类型(enum):如
enum color {red, blue, green}
。
- 数组:如
自定义数据类型:
- 使用
typedef
创建新的类型别名。
- 使用
2. 按存储类别分类:
根据变量的 生命周期 和 存储位置,C语言中的变量可以分为:
自动变量(Auto):
- 默认类型,函数或代码块内定义的局部变量。
- 存储在 栈(Stack) 中。
- 生命周期:随函数调用开始,随函数结束销毁。
- 默认未初始化,需显式初始化。
示例:
1
2
3void func() {
int a = 10; // 自动变量
}静态变量(Static):
- 使用
static
关键字声明的变量。 - 存储在 静态存储区,生命周期贯穿程序的整个运行过程。
- 只初始化一次,且值在函数调用间保持不变。
示例:
1
2
3
4
5void func() {
static int count = 0; // 静态变量
count++;
printf("%d\n", count);
}- 使用
全局变量(Global):
- 在所有函数外部定义的变量,称为全局变量。
- 存储在 静态存储区。
- 生命周期贯穿整个程序运行,作用域是整个文件。
示例:
1
2
3
4int global = 0; // 全局变量
void func() {
printf("%d\n", global);
}寄存器变量(Register):
- 使用
register
关键字声明,建议将变量存储在CPU寄存器中,以提高访问速度。 - 不保证一定存储在寄存器中,具体由编译器决定。
- 无法获取寄存器变量的地址(不能使用
&
)。
示例:
1
2
3void func() {
register int i = 0; // 寄存器变量
}- 使用
3. 按作用域分类:
变量的作用域是指变量在程序中有效的范围:
局部变量:
- 在函数或代码块内定义的变量,作用域仅限于该函数或代码块。
- 生命周期随函数的调用开始,结束后变量被销毁。
全局变量:
- 在所有函数外部定义的变量。
- 作用域是整个源文件,生命周期贯穿程序的运行过程。
块级变量:
- 在代码块
{}
中定义,作用域仅限于该代码块。
- 在代码块
文件作用域变量:
- 使用
static
修饰的全局变量,只能在当前文件内访问,具有内部链接属性。
- 使用
4. 按初始化分类:
未初始化变量:
- 自动变量默认值是 不确定的(随机值)。
- 静态变量和全局变量默认初始化为 0 或 NULL。
显式初始化变量:
在定义时赋初始值,例如:
1
int a = 10;
隐式初始化变量:
- 静态变量或全局变量未显式赋值时默认初始化为0。
5. 按常量性分类:
普通变量:
- 值可以在程序运行时改变。
常变量(const修饰):
- 使用
const
关键字定义,变量的值不能修改。
示例:
1
const int a = 5; // 常变量
- 使用
ASCII码表
注意控制字符<数字<<大写字母<<小写字母
控制字符 (0–31 和 127)
十进制 | 十六进制 | 字符 | 描述 |
---|---|---|---|
0 | 0x00 | NUL | 空字符 |
1 | 0x01 | SOH | 标题开始 |
2 | 0x02 | STX | 正文开始 |
3 | 0x03 | ETX | 正文结束 |
4 | 0x04 | EOT | 传输结束 |
5 | 0x05 | ENQ | 请求 |
6 | 0x06 | ACK | 确认 |
7 | 0x07 | BEL | 响铃 |
8 | 0x08 | BS | 退格 |
9 | 0x09 | TAB | 水平制表符(Tab 键) |
10 | 0x0A | LF | 换行(Line Feed) |
11 | 0x0B | VT | 垂直制表符 |
12 | 0x0C | FF | 换页符 |
13 | 0x0D | CR | 回车(Carriage Return) |
14 | 0x0E | SO | 移出 |
15 | 0x0F | SI | 移入 |
16 | 0x10 | DLE | 数据链路转义 |
17 | 0x11 | DC1 | 设备控制1 |
18 | 0x12 | DC2 | 设备控制2 |
19 | 0x13 | DC3 | 设备控制3 |
20 | 0x14 | DC4 | 设备控制4 |
21 | 0x15 | NAK | 否认 |
22 | 0x16 | SYN | 同步空闲 |
23 | 0x17 | ETB | 传输块结束 |
24 | 0x18 | CAN | 取消 |
25 | 0x19 | EM | 媒体结束 |
26 | 0x1A | SUB | 替补 |
27 | 0x1B | ESC | 转义(Escape) |
28 | 0x1C | FS | 文件分隔符 |
29 | 0x1D | GS | 组分隔符 |
30 | 0x1E | RS | 记录分隔符 |
31 | 0x1F | US | 单元分隔符 |
127 | 0x7F | DEL | 删除(Delete) |
可打印字符 (32–126)
空格和标点符号
十进制 | 十六进制 | 字符 | 描述 |
---|---|---|---|
32 | 0x20 | (空格) | 空格 |
33 | 0x21 | ! | 感叹号 |
34 | 0x22 | “ | 双引号 |
35 | 0x23 | # | 井号 |
36 | 0x24 | $ | 美元符号 |
37 | 0x25 | % | 百分号 |
38 | 0x26 | & | 和号 |
39 | 0x27 | ‘ | 单引号 |
40 | 0x28 | ( | 左括号 |
41 | 0x29 | ) | 右括号 |
42 | 0x2A | * | 星号 |
43 | 0x2B | + | 加号 |
44 | 0x2C | , | 逗号 |
45 | 0x2D | - | 减号 |
46 | 0x2E | . | 句号 |
47 | 0x2F | / | 斜杠 |
数字 0–9
十进制 | 十六进制 | 字符 | 描述 |
---|---|---|---|
48 | 0x30 | 0 | 数字 0 |
49 | 0x31 | 1 | 数字 1 |
50 | 0x32 | 2 | 数字 2 |
51 | 0x33 | 3 | 数字 3 |
52 | 0x34 | 4 | 数字 4 |
53 | 0x35 | 5 | 数字 5 |
54 | 0x36 | 6 | 数字 6 |
55 | 0x37 | 7 | 数字 7 |
56 | 0x38 | 8 | 数字 8 |
57 | 0x39 | 9 | 数字 9 |
其他标点符号
十进制 | 十六进制 | 字符 | 描述 |
---|---|---|---|
58 | 0x3A | : | 冒号 |
59 | 0x3B | ; | 分号 |
60 | 0x3C | < | 小于号 |
61 | 0x3D | = | 等号 |
62 | 0x3E | > | 大于号 |
63 | 0x3F | ? | 问号 |
64 | 0x40 | @ | at 符号 |
大写字母 A–Z
十进制 | 十六进制 | 字符 | 描述 |
---|---|---|---|
65 | 0x41 | A | 大写字母 A |
66 | 0x42 | B | 大写字母 B |
… | … | … | … |
90 | 0x5A | Z | 大写字母 Z |
小写字母 a–z
十进制 | 十六进制 | 字符 | 描述 |
---|---|---|---|
97 | 0x61 | a | 小写字母 a |
98 | 0x62 | b | 小写字母 b |
… | … | … | … |
122 | 0x7A | z | 小写字母 z |
更多标点符号
十进制 | 十六进制 | 字符 | 描述 |
---|---|---|---|
91 | 0x5B | [ | 左方括号 |
92 | 0x5C | |反斜杠 | |
93 | 0x5D | ] | 右方括号 |
94 | 0x5E | ^ | 插入符号 |
95 | 0x5F | _ | 下划线 |
96 | 0x60 | ` | 反引号 |
123 | 0x7B | { | 左花括号 |
124 | 0x7C | ||
125 | 0x7D | } | 右花括号 |
126 | 0x7E | ~ | 波浪号 |
C语言语句类型
C语言中的语句可以分为以下几类:
- 表达式语句 (Expression Statements)
- 选择语句 (Selection Statements)
- 循环语句 (Looping Statements)
- 跳转语句 (Jump Statements)
- 复合语句 (Compound Statements)
- 空语句 (Empty Statements)