doc: update c.md (#911)
This commit is contained in:
parent
b3893d8478
commit
6c8217202a
152
docs/c.md
152
docs/c.md
@ -54,11 +54,21 @@ int y = 6;
|
|||||||
int sum = x + y; // 添加变量相加
|
int sum = x + y; // 添加变量相加
|
||||||
// 声明多个变量
|
// 声明多个变量
|
||||||
int x = 5, y = 6, z = 50;
|
int x = 5, y = 6, z = 50;
|
||||||
|
int a, b, c = 10;
|
||||||
|
|
||||||
|
//仅声明变量不初始化
|
||||||
|
int result;
|
||||||
|
// 如果未初始化,变量的值是未定义的,使用它会导致错误的结果。
|
||||||
|
// 此时,变量的值是随机的,因此在使用该变量之前必须进行初始化。
|
||||||
|
result = result + 10; // 错误:未初始化的变量 result 会导致不可预测的结果
|
||||||
|
|
||||||
|
// 部分编译器会输出 Warning,警告未初始化的变量可能导致未定义行为。
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 常量 Constants
|
### 常量 Constants
|
||||||
|
|
||||||
常量在 C 语言中我们一般理解为不能被改变的值,活用常量与符号常量
|
常量在 C 语言中我们一般理解为不能被改变的值,活用常量与符号常量,可以使代码更加清晰和安全
|
||||||
|
|
||||||
```c
|
```c
|
||||||
const int minutesPerHour = 60;
|
const int minutesPerHour = 60;
|
||||||
@ -71,13 +81,36 @@ const float PI = 3.14;
|
|||||||
const int BIRTHYEAR = 1980;
|
const int BIRTHYEAR = 1980;
|
||||||
```
|
```
|
||||||
|
|
||||||
|
说明与补充:
|
||||||
|
1. **常量命名规范**:常量通常使用全大写字母,多个单词之间用下划线分隔(例如 BIRTHYEAR、MAX_LENGTH)。
|
||||||
|
|
||||||
|
2. **`#define` 与 `const`**:
|
||||||
|
- **`#define`**:宏常量通常在预处理阶段进行替换,不进行类型检查;
|
||||||
|
- **`const`**:类型安全的常量,编译器可以检查类型,一般更推荐使用 `const`
|
||||||
|
|
||||||
|
3. **数组大小**:可以使用 `const` 来定义数组的常量大小,这样编译器会将其作为编译时常量处理
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 注释
|
### 注释
|
||||||
|
|
||||||
```c
|
```c
|
||||||
// 这是一个注释
|
// 这是一个注释
|
||||||
printf("Hello World!"); // 这是一个注释
|
printf("Hello World!"); // 这是一个注释
|
||||||
/* 多行注释,上面的代码将打印出 Hello World!
|
/*
|
||||||
到屏幕上,真是太棒了 */
|
多行注释:用于注释跨多行的内容
|
||||||
|
上面的代码将打印出 Hello World! 到屏幕上
|
||||||
|
注意:多行注释不能嵌套,否则会导致编译错误
|
||||||
|
*/
|
||||||
|
```
|
||||||
|
**注意**:
|
||||||
|
单行注释`//`可以嵌套,`////////这种注释也是对的`
|
||||||
|
但行内注释应避免过长,以免影响代码可读性
|
||||||
|
|
||||||
|
多行注释不能嵌套,否则会导致编译错误(详见下文 [### Warning 和 Error](#warning-和-error) )
|
||||||
|
```c
|
||||||
|
/* 这是一个多行注释的开始
|
||||||
|
/* 这是嵌套的多行注释,C语言不支持 */
|
||||||
```
|
```
|
||||||
|
|
||||||
### 打印文本
|
### 打印文本
|
||||||
@ -93,8 +126,9 @@ printf("Value = %f", f);
|
|||||||
short a = 0b1010110; // 2 进制数字
|
short a = 0b1010110; // 2 进制数字
|
||||||
int b = 02713; // 8 进制数字
|
int b = 02713; // 8 进制数字
|
||||||
long c = 0X1DAB83; // 16 进制数字
|
long c = 0X1DAB83; // 16 进制数字
|
||||||
|
//变量a和c分别为short和long型,所以输出必须加上对应的修饰符h和l
|
||||||
|
|
||||||
// 以 8 进制形似输出
|
// 以 8 进制形式输出
|
||||||
printf("a=%ho, b=%o, c=%lo\n", a, b, c);
|
printf("a=%ho, b=%o, c=%lo\n", a, b, c);
|
||||||
// 输出 => a=126, b=2713, c=7325603
|
// 输出 => a=126, b=2713, c=7325603
|
||||||
|
|
||||||
@ -119,6 +153,7 @@ int b1=56720, b2=9999, b3=20098;
|
|||||||
int c1=233, c2=205, c3=1;
|
int c1=233, c2=205, c3=1;
|
||||||
int d1=34, d2=0, d3=23;
|
int d1=34, d2=0, d3=23;
|
||||||
|
|
||||||
|
// %-9d: 十进制输出,最少宽度为9,左对齐
|
||||||
printf("%-9d %-9d %-9d\n", a1, a2, a3);
|
printf("%-9d %-9d %-9d\n", a1, a2, a3);
|
||||||
printf("%-9d %-9d %-9d\n", b1, b2, b3);
|
printf("%-9d %-9d %-9d\n", b1, b2, b3);
|
||||||
printf("%-9d %-9d %-9d\n", c1, c2, c3);
|
printf("%-9d %-9d %-9d\n", c1, c2, c3);
|
||||||
@ -134,7 +169,29 @@ printf("%-9d %-9d %-9d\n", d1, d2, d3);
|
|||||||
34 0 23
|
34 0 23
|
||||||
```
|
```
|
||||||
|
|
||||||
`%-9d` 中,`d` 表示以 `10` 进制输出,`9` 表示最少占 `9` 个字符的宽度,宽度不足以空格补齐,`-` 表示左对齐
|
`%-9d` 中,`d` 表示以 `10` 进制输出,`9` 表示最少占 `9` 个字符的宽度,宽度不足以空格补齐,`-` 表示左对齐,如果不使用左对齐则默认右对齐
|
||||||
|
|
||||||
|
对于整型数据,假设:
|
||||||
|
```c
|
||||||
|
int a = 12345;
|
||||||
|
printf(“%md”,a);
|
||||||
|
```
|
||||||
|
1. 若 m <= 实际数据的宽度,则按实际情况输出
|
||||||
|
2. 若 m > 实际数据的宽度,则在实际数据的左边用空格补齐
|
||||||
|
3. `printf(“%0md”,a);` 则实际的结果不够 m 位的在数据的左边用0补齐
|
||||||
|
|
||||||
|
对于浮点型数据,宽度=整数部分的位数+小数点+小数部分的宽度
|
||||||
|
假设:
|
||||||
|
```c
|
||||||
|
float a = 1.2345;
|
||||||
|
printf(“%m.nf”,a); //m --整个数据的宽度,n--小数位数
|
||||||
|
```
|
||||||
|
1. 实际小数位数>n,截去小数右边多余的小数,截去的第一位要注意四舍五入
|
||||||
|
2. 实际小数位数< n,在小数的最后补0
|
||||||
|
3. 若m省略则写作%.n ,整数部分按照实际输出,小数部分按照以上两个规则进行
|
||||||
|
4. m < n+1,自动突破宽度为m的限制,按照实际数据进行输出
|
||||||
|
5. m > n+1,整个数据的最左边补空格
|
||||||
|
|
||||||
|
|
||||||
### 字符串 Strings
|
### 字符串 Strings
|
||||||
|
|
||||||
@ -191,14 +248,37 @@ if (time < 10) {
|
|||||||
printf("晚上好!");
|
printf("晚上好!");
|
||||||
}
|
}
|
||||||
// 输出 -> "晚上好!"
|
// 输出 -> "晚上好!"
|
||||||
|
|
||||||
|
int time = 10;
|
||||||
|
if (time > 8) {
|
||||||
|
//再嵌套一个if
|
||||||
|
if (time < 12) {
|
||||||
|
printf("中午好!")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 输出 -> "中午好!"
|
||||||
```
|
```
|
||||||
|
|
||||||
### 三元运算符
|
### 三元运算符
|
||||||
<!--rehype:wrap-class=col-span-2-->
|
<!--rehype:wrap-class=col-span-2-->
|
||||||
|
三元运算符(? :)是一种简洁的条件判断方式,常用于根据条件选择表达式的值,由三个部分组成:
|
||||||
|
- 一个条件表达式
|
||||||
|
- 条件为真时的结果
|
||||||
|
- 条件为假时的结果
|
||||||
|
基本语法:`(condition) ? expression1 : expression2;`
|
||||||
|
如果`condition`为真,则返回`expression1`否则返回`expression2`。
|
||||||
|
|
||||||
```c
|
```c
|
||||||
int time = 20;
|
int time = 20;
|
||||||
(time < 18) ? printf("再会!") : printf("晚上好!");
|
(time < 18) ? printf("再会!") : printf("晚上好!");
|
||||||
|
// 输出 -> "晚上好!"
|
||||||
|
```
|
||||||
|
|
||||||
|
三元运算符可以嵌套使用,但嵌套层级太多会导致代码可读性下降,不建议在实际场景使用
|
||||||
|
```c
|
||||||
|
int time = 22;
|
||||||
|
printf((time < 10) ? "早上好!" : (time < 20) ? "再会!" : "晚上好!");
|
||||||
|
// 输出 -> "晚上好!"
|
||||||
```
|
```
|
||||||
|
|
||||||
### Switch
|
### Switch
|
||||||
@ -805,6 +885,68 @@ int main(void) {
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Warning 和 Error
|
||||||
|
<!--rehype:wrap-class=row-span-2-->
|
||||||
|
|
||||||
|
在 C 语言中,警告(Warning)和错误(Error)是编译器用于标识代码潜在问题或阻止代码编译的两种机制
|
||||||
|
|
||||||
|
**警告**:
|
||||||
|
警告提示代码中可能存在的问题,但不会阻止代码编译。处理警告可以提升代码质量和可移植性。
|
||||||
|
|
||||||
|
**常见警告示例**:
|
||||||
|
1. 未使用的变量
|
||||||
|
`int x; printf("%d",x);`
|
||||||
|
2. 类型隐式转换(可能导致数据丢失)
|
||||||
|
`int x = 3.14; //浮点数被隐式转换`
|
||||||
|
`int a = 2147483647 + 1; //可能溢出`
|
||||||
|
3. 函数声明与定义不匹配
|
||||||
|
|
||||||
|
**错误**:
|
||||||
|
警告提示代码中可能存在的问题,但不会阻止代码编译。处理警告可以提升代码质量和可移植性。
|
||||||
|
|
||||||
|
**常见错误示例**:
|
||||||
|
1. 语法错误(如缺少分号)
|
||||||
|
`int x=1 `
|
||||||
|
2. 函数定义冲突
|
||||||
|
```C
|
||||||
|
void func(int);
|
||||||
|
void func(double);
|
||||||
|
```
|
||||||
|
3. 函数或变量未定义
|
||||||
|
`y = 10; printf("%d",y);`
|
||||||
|
4. 头文件缺失或冲突
|
||||||
|
`#include <unknown.h>`
|
||||||
|
|
||||||
|
**使用编译器指令控制警告和错误**:
|
||||||
|
1. 抑制警告
|
||||||
|
可以使用编译器选项来关闭特定的警告,例如在 GCC 中:
|
||||||
|
```GCC
|
||||||
|
gcc -w file.c # 禁用所有警告
|
||||||
|
gcc -Wall file.c # 启用所有常见警告
|
||||||
|
gcc -Werror file.c # 将警告视为错误
|
||||||
|
```
|
||||||
|
2. 使用 #pragma 控制警告
|
||||||
|
在某些编译器中,可以使用`#pragma`指令启用或禁用警告
|
||||||
|
```C
|
||||||
|
#include <stdio.h>
|
||||||
|
#pragma warning(disable : 4996) // 禁用警告(适用于 MSVC 编译器)
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
printf("Hello, world!");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**总结**
|
||||||
|
| 区别点 | Warning(警告) | Error(错误) |
|
||||||
|
|------------------|----------------------------------------|----------------------------------------|
|
||||||
|
| 严重程度 | 程序可继续编译,但可能存在隐患 | 编译无法完成,必须修复 |
|
||||||
|
| 编译结果 | 生成可执行文件 | 无法生成可执行文件 |
|
||||||
|
| 触发原因 | 潜在问题,例如隐式转换或未使用的变量 | 语法或语义错误,例如语法错误或未定义变量 |
|
||||||
|
| 修复必要性 | 可选择修复,但建议修复以避免潜在问题 | 必须修复才能继续编译 |
|
||||||
|
| 编译器选项调整 | 可以忽略或转换为错误(如 `-Werror`) | 无法调整,必须修复 |
|
||||||
|
|
||||||
|
|
||||||
函数
|
函数
|
||||||
----
|
----
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user