基础语法
注:要查看完整的函数请阅读cppreference帮助文档,笔记中的重点在于介绍使用的细节、帮助文档中未详细介绍的用法、使用实例等
C语言版本演进核心脉络总结:
| 版本 | 发布时间 | 核心标签 | 关键贡献(一句话总结) | 目前主流度 |
|---|---|---|---|---|
| K&R C | 1978 年 | 事实标准 | 首次系统定义 C 语言,为后续标准化奠定基础 | 淘汰(仅历史参考) |
| C89/C90 | 1989/1990 | 首个官方标准 | 统一语法与库函数,解决可移植性问题 | 完全兼容(基础) |
| C95 | 1995 年 | 细节补充 | 支持宽字符,修正库函数细节 | 融入后续标准 |
| C99 | 1999 年 | 现代 C 起点 | 引入变长数组、布尔类型、固定宽度整数,大幅提升工程实用性 | 极高(工业主流) |
| C11 | 2011 年 | 安全与多线程 | 新增原子操作、标准多线程库,增强安全性 | 高(推荐新项目) |
| C17/C18 | 2017/2018 | 修正版 | 修复 C11 漏洞,无新特性,提升稳定性 | 高(兼容 C11) |
| C23 | 2023 年 | 最新标准 | 简化语法(如nullptr)、增强安全性,适配现代需求 |
逐步普及中 |
基本输入输出函数
scanf - 标准流输入函数
- 函数原型:
int scanf(const char *format, ...); (c99) - 依赖库:
<stdio.h>
注:
- scanf在输入的时候,不能读取空格后的数据,因为空格会被视为终止符
- 格式字符串的特殊写法如下
格式字符串 说明 %5d 限制长度为5的整型(打印时,不足补空格) %5f 限制长度为5的浮点型(小数点也算一位,后面舍去)
printf - 标准流输出函数
略
Windows设置控制台为UTF-8
#include <windows.h>
SetConsoleOutputCP(CP_UTF8);
SetConsoleCP(CP_UTF8);数据类型
数据类型及其占用内存空间
| 类型 | 说明 | 占用字节 |
|---|---|---|
| char | 字符型 | 1 |
| short | 短整型 | 2 |
| int | 整型 | 4 |
| long | 长整型 | 4或8 |
| float | 单精度浮点型 | 4 |
| double | 双精度浮点型 | 8 |
注:C语言想用布尔值,需要引入头文件
<stdbool.h>
变量
变量命名规则
- 只能以字母、下划线开头
- 不能以纯数字开头
- 不能使用语言的关键字
- 变量名应具有意义,且简单明了
- 变量名应区分大小写
变量的作用域(Scope)
局部变量:代码块的内部
全局变量:整个程序(所有的源文件和头文件,除非加static修饰)
注:局部变量和全局变量的名词可以重复,且局部变量优先
变量的初始化
在栈空间开辟
创建时,未初始化,且为随机值
在堆空间开辟
创建时,未初始化,且为随机值
在静态区开辟
创建时,数据就已初始化为0
注:
- 变量可以声明多次,但只能定义一次
- 变量名称只能是数字、字母、下划线;且只能以字母下划线打头
- 声明外部文件中的函数:extern void function(int);
- 使用外部文件内的结构体变量时,还需要对结构体变量进行前置声明,如:structBinaryTreeNode;//前置声明二叉树类型
常量
常量的分类
| 类型 | 实例 | 说明 |
|---|---|---|
| 字面常量 | “1” | |
| const修饰的变常量 | const int num = 1; |
可以通过num指针修改 |
| const修饰的指针 | const int* p = # |
无法通过指针修改指向的变量 |
| #define定义的标识符常量 | #define max 100 |
预处理内容,要写在代码区外 |
| 枚举常量 | enum { male, female }; |
从0开始枚举 |
字面常量
整型字面常量
类型 表达方式 十进制数字 无前缀,直接写 二进制数字 前缀 0b或0B八进制数字 前缀 0十六进制数字 前缀 0x字符字面常量
如
'a'浮点型字面常量
类型 表达方式 普通的(默认为double) 3.14 float类型的 3.14f 科学计数法 1E6
const定义的常变量
书写格式:const 类型 常量名 = 常量值;
注:通常#define定义的、const定义的、(C语言中枚举常量),常量名一般用全大写字母命名
数组、字符
数组变量
概念:一组相同类型元素的集合
定义方法:
类型 + 变量名词 + [元素个数];注:元素个数中只能放常量,也可以不用具体说明元素的个数
调用:规定第一个元素下标为0,以此类推。如arr[5]代表arr数组中第6个元素
字符串的结束标志
调试如下代码:char haha[10]= "hello bite";
会发现,字符串结束标志是\0
转义字符
| 转义字符 | 含义 |
|---|---|
| 换行符 | |
| 水平制表符 | |
| 垂直指标符 | |
| 警告符 | |
| 回车符 | |
| 退格符 | |
| \ | 普通斜杠 |
| ' | 单引号 |
| “ | 双引号 |
| ddd为1至8个八进制数字,字符表示十进制数在ASCII码表上字符 | |
| dd代表2个十六进制的数字(如),字符表示十进制数在ASCII码表上字符 |
分支与循环
if语法
| 语句 | 含义 | 注意事项 |
|---|---|---|
| if (表达式) | 若表达式为真,则执行后面的语句 | 只能控制后面的一条语句 |
| else if (表达式) | 与if同理,但先判断if,若if判断执行了,则不会被执行 | 只能控制后面的一条语句 |
| else | 在if、if else都判断且未被执行后,执行else后的语句 | 只能控制后面的一条语句,且只与最近、未匹配的if匹配 |
switch语法(实例)
switch (day) {
case 1:
case 2:
case 3:
case 4:
case 5:
printf("工作日");
break;
case 6:
case 7:
printf("休息日");
break;
default:
printf("错误!");
break;
}注:
- case后必须是整型常量表达式
- switch()内的表达式决定从哪里进去,而break决定哪里出来
- default是在没有case所对应的情况,默认执行的语句块
for语法
for (初始化; 循环条件; 调整)
循环体;注:
- 进入for循环时,初始化只会执行一次
- 只有判断为真才能开始一次循环
- 每次循环结束后会执行一次调整
- for循环的初始化、判断、调整都能省略。判断省略时,判断恒为真
do while语法
do
循环体;
while(判断);注:
- 判断为真时才能开始下一次循环
- do while循环至少执行一次循环
main函数的其他写法
带参数的main函数
语法
// 或 int main(int argc, char** argv); int main(int argc, char* argv[]) { return 0; }含义
argc:参数的个数,至少1个(argument count)argv:参数字符串数组(argument vector)
注:
- 第一个参数为 程序的可执行文件名,例如
D:\Project1\x64\Debug\Project1.exe - Java里面为
public static void main(String[] args)
注意事项
当输入参数需要含带空格的字符串时,需要使用
"来包含,例如:Project1.exe "a b b"此时,就会识别到两个参数:
Project1.exe、a b b,否则会英文空格把它分成多个参数