C 语言是结构化、面向过程的编程语言,语法简洁且贴近底层,是编程入门的经典选择。本文从程序结构、数据类型、变量与常量、运算符、流程控制、函数、数组、指针(基础) 等核心维度,详解 C 语言基础语法,兼顾易懂性和实用性。
一、C 程序的基本结构
一个完整的 C 程序由预处理指令、全局声明、函数(核心) 三部分组成,最基础的 “Hello World” 示例如下:
c
运行
// 1. 预处理指令:引入标准输入输出头文件
#include <stdio.h>
// 2. 主函数:程序的入口(必须有且仅有一个main函数)
int main() {
// 语句:输出字符串,以分号结束
printf("Hello, C Language!\n");
// 返回值:0表示程序正常结束
return 0;
}
核心说明:
- 预处理指令:以
#开头,在编译前执行,常见的有#include(引入头文件)、#define(宏定义)、#ifdef(条件编译)等; - 函数:C 程序的执行单元,
main()是程序入口,格式为:返回值类型 函数名(参数列表) { 函数体 }; - 语句:每个可执行语句以
;结尾,\n是换行符; - 注释:
- 单行注释:
// 注释内容(C99 标准支持); - 多行注释:
/* 注释内容 */(不可嵌套)。
- 单行注释:
二、数据类型
C 语言数据类型分为基本类型、构造类型、指针类型、空类型 四类,基础阶段重点掌握基本类型:
| 类型分类 | 具体类型 | 关键字 | 占用字节(32/64 位系统) | 取值范围示例 |
|---|---|---|---|---|
| 整型 | 短整型 | short | 2 | -32768 ~ 32767 |
| 整型 | int | 4 | -2^31 ~ 2^31-1 | |
| 长整型 | long | 4/8 | 随系统,至少与 int 一致 | |
| 无符号整型 | unsigned int | 4 | 0 ~ 2^32-1 | |
| 浮点型 | 单精度浮点型 | float | 4 | 有效数字 6~7 位 |
| 双精度浮点型 | double | 8 | 有效数字 15~16 位 | |
| 字符型 | 字符型 | char | 1 | -128 ~ 127(或 0~255,取决于编译器) |
补充:
- 字符型
char本质是存储 ASCII 码(如'a'对应 97,'0'对应 48); - 浮点型默认是
double,定义float需加后缀f(如float f = 3.14f;); - 空类型
void:用于函数返回值(无返回值)、函数参数(无参数)、指针类型(void*)。
三、变量与常量
1. 变量
变量是程序运行中可修改的存储单元,定义格式:类型名 变量名 [= 初始值];
规则:
- 变量名由字母、数字、下划线组成,不能以数字开头,区分大小写(如
num和Num是两个变量); - 不能使用 C 语言关键字(如
int、if、for等)作为变量名; - 变量必须先定义后使用,建议初始化(避免随机值)。
示例:
c
运行
#include <stdio.h>
int main() {
// 整型变量,未初始化
int age;
// 初始化
age = 20;
// 字符变量,直接初始化
char gender = 'M';
// 浮点变量
float score = 95.5f;
printf("年龄:%d,性别:%c,分数:%.1f\n", age, gender, score);
return 0;
}
2. 常量
常量是程序运行中不可修改的量,分为 4 类:
| 常量类型 | 示例 | 说明 |
|---|---|---|
| 字面常量 | 100、3.14、’A’、”abc” | 直接书写的常量值 |
| 宏常量 | #define PI 3.14159 | 预处理阶段替换,无类型检查 |
| 枚举常量 | enum {MON, TUE=2, WED}; | MON=0,TUE=2,WED=3(默认自增) |
| 常变量 | const int num = 10; | 有类型检查,本质是 “只读变量” |
示例:
c
运行
#include <stdio.h>
// 宏常量
#define PI 3.14159
// 枚举常量
enum Week {MON, TUE, WED};
int main() {
// 常变量
const int radius = 5;
// 字面常量
float area = PI * radius * radius;
printf("圆面积:%.2f\n", area);
printf("周二:%d\n", TUE); // 输出1
return 0;
}
四、运算符
C 语言运算符按功能分为算术、赋值、关系、逻辑、位运算、三目 等,核心如下:
1. 算术运算符
| 运算符 | 功能 | 示例 | 注意 |
|---|---|---|---|
| +、-、*、/ | 加减乘除 | 10/3=3(整型除法取整) | 除数不能为 0;浮点数除法保留小数 |
| % | 取模(求余) | 10%3=1 | 仅适用于整型 |
| ++、– | 自增 / 自减 | a++(后增)、++a(前增) | 前增:先加 1 再使用;后增:先使用再加 1 |
示例:
c
运行
int a = 5;
// 先使用a=5,再a=6
printf("%d\n", a++);
// 先a=7,再输出7
printf("%d\n", ++a);
2. 赋值运算符
- 基本赋值:
=(如x = 10;); - 复合赋值:
+=、-=、*=、/=、%=(如x += 5等价于x = x + 5)。
3. 关系运算符(返回 0/1,0 为假,非 0 为真)
| 运算符 | 功能 | 示例 |
|---|---|---|
| >、<、>=、<= | 大于、小于、大于等于、小于等于 | 5>3=1,5<=3=0 |
| == | 等于 | 5==5=1,5==3=0 |
| != | 不等于 | 5!=3=1 |
4. 逻辑运算符(操作数为 0 / 非 0,返回 0/1)
| 运算符 | 功能 | 示例 | 短路特性 |
|---|---|---|---|
| && | 逻辑与 | (5>3)&&(2<1)=0 | 左假则右不执行 |
| || | 逻辑或 | (5>3)||(2<1)=1 | 左真则右不执行 |
| ! | 逻辑非 | !(5>3)=0 | – |
5. 三目运算符(条件运算符)
格式:条件 ? 表达式1 : 表达式2
规则:条件为真执行表达式 1,否则执行表达式 2。
示例:
c
运行
int a = 10, b = 20;
// max=20
int max = (a > b) ? a : b;
6. 运算符优先级(核心)
从高到低:() > 单目(++、–、!) > 算术(*、/、% > +、-) > 关系 > 逻辑(&& > ||) > 三目 > 赋值。
建议:复杂表达式用()明确优先级,提升可读性。
五、流程控制
C 语言通过顺序、选择、循环 控制程序执行流程,核心是选择和循环。
1. 选择结构
(1)if 语句
格式:
c
运行
// 单分支
if (条件) { 语句块; }
// 双分支
if (条件) { 语句块1; }
else { 语句块2; }
// 多分支
if (条件1) { 语句块1; }
else if (条件2) { 语句块2; }
...
else { 语句块n; }
示例:
c
运行
int score = 85;
if (score >= 90) {
printf("优秀\n");
} else if (score >= 80) {
printf("良好\n");
} else {
printf("及格\n");
}
(2)switch 语句
适用于 “多值匹配” 场景,格式:
c
运行
switch (表达式) {
case 常量1: 语句块1; break;
case 常量2: 语句块2; break;
...
default: 语句块n; break;
}
注意:
- 表达式必须是整型 / 字符型;
break用于跳出 switch,否则会 “穿透” 到下一个 case;default可选,匹配不到 case 时执行。
示例:
c
运行
int day = 2;
switch (day) {
case 1: printf("周一\n"); break;
case 2: printf("周二\n"); break;
default: printf("其他\n"); break;
}
2. 循环结构
(1)for 循环(适合已知循环次数)
格式:for (初始化表达式; 条件表达式; 更新表达式) { 循环体; }
执行流程:初始化 → 判断条件 → 执行循环体 → 更新 → 再判断…
示例(输出 1~5):
c
运行
for (int i = 1; i <= 5; i++) {
printf("%d ", i);
}
(2)while 循环(适合未知循环次数)
格式:while (条件) { 循环体; }
执行流程:先判断条件,为真则执行循环体。
示例(计算 1~100 求和):
c
运行
int i = 1, sum = 0;
while (i <= 100) {
sum += i;
i++;
}
printf("sum = %d\n", sum);
(3)do-while 循环(至少执行一次循环体)
格式:do { 循环体; } while (条件);
执行流程:先执行循环体,再判断条件。
示例:
c
运行
int num;
do {
printf("输入一个正数:");
scanf("%d", &num);
} while (num <= 0);
(4)循环控制关键字
break:跳出当前循环(switch / 循环);continue:跳过本次循环剩余语句,进入下一次循环;goto:无条件跳转(不建议使用,易破坏结构)。
示例(break 跳出循环):
c
运行
for (int i = 1; i <= 5; i++) {
if (i == 3) break;
printf("%d ", i); // 输出1 2
}
六、函数
函数是 C 程序的基本模块,实现代码复用,核心要素:定义、声明、调用。
1. 函数定义
格式:
c
运行
返回值类型 函数名(参数类型1 参数名1, 参数类型2 参数名2, ...) {
// 函数体
语句块;
// 返回值(void类型无需return)
return 返回值;
}
示例(求两数最大值):
c
运行
// 定义函数
int max(int a, int b) {
return (a > b) ? a : b;
}
2. 函数声明
如果函数定义在调用之后,需先声明(告诉编译器函数的 “接口”):
格式:返回值类型 函数名(参数类型1, 参数类型2, ...);
示例:
c
运行
#include <stdio.h>
// 函数声明
int max(int a, int b);
int main() {
// 函数调用
int res = max(10, 20);
printf("最大值:%d\n", res);
return 0;
}
// 函数定义
int max(int a, int b) {
return (a > b) ? a : b;
}
3. 函数参数
- 形参:函数定义时的参数(如
max中的a、b); - 实参:函数调用时传入的参数(如
max(10,20)中的 10、20); - 传值调用:默认方式,形参是实参的拷贝,修改形参不影响实参;
- 传址调用:通过指针传递,修改形参指向的内容会影响实参(后续指针部分详解)。
4. 主函数参数(扩展)
main函数支持参数传递(命令行参数),格式:
c
运行
int main(int argc, char *argv[]) {
// argc:参数个数;argv:参数数组(argv[0]是程序名)
printf("参数个数:%d\n", argc);
for (int i = 0; i < argc; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
return 0;
}
七、数组(基础)
数组是相同类型数据的有序集合,分为一维数组和二维数组(基础阶段重点)。
1. 一维数组
(1)定义:类型名 数组名[数组长度];
(2)初始化:
c
运行
// 完全初始化
int arr[5] = {1,2,3,4,5};
// 部分初始化(未初始化的元素为0)
int arr[5] = {1,2};
// 省略长度(长度由初始化元素个数决定)
int arr[] = {1,2,3};
(3)访问:数组名[下标](下标从 0 开始)
示例(遍历数组):
c
运行
#include <stdio.h>
int main() {
int arr[5] = {10,20,30,40,50};
// 遍历数组
for (int i = 0; i < 5; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
return 0;
}
2. 二维数组
(1)定义:类型名 数组名[行长度][列长度];
(2)初始化:
c
运行
// 完全初始化
int arr[2][3] = {{1,2,3}, {4,5,6}};
// 部分初始化(未初始化的元素为0)
int arr[2][3] = {{1}, {4}};
// 省略行长度(列长度不能省)
int arr[][3] = {{1,2}, {3,4}};
(3)访问:数组名[行下标][列下标]
示例(遍历二维数组):
c
运行
int arr[2][3] = {{1,2,3}, {4,5,6}};
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
八、指针(基础)
指针是 C 语言的核心特性,本质是存储内存地址的变量。
1. 指针的定义与基本使用
格式:类型名 *指针变量名;
&:取地址符(获取变量的内存地址);*:解引用符(通过地址访问变量的值)。
示例:
c
运行
#include <stdio.h>
int main() {
int a = 10;
// 定义指针变量p,存储a的地址
int *p = &a;
// 输出a的地址(如0x7ffeefbff5c4)
printf("a的地址:%p\n", &a);
// 输出p的值(与a的地址相同)
printf("p的值:%p\n", p);
// 解引用:输出a的值(10)
printf("*p的值:%d\n", *p);
// 修改a的值为20
*p = 20;
printf("a的值:%d\n", a); // 输出20
return 0;
}
2. 指针与数组
数组名本质是数组首元素的地址(常量,不可修改),因此可通过指针访问数组:
c
运行
int arr[5] = {1,2,3,4,5};
// p指向数组首元素
int *p = arr;
for (int i = 0; i < 5; i++) {
// 等价于arr[i]
printf("%d ", *(p + i));
}
九、常见语法注意事项
- 分号问题:语句必须以
;结尾,if/for/while的条件后不要多加分号(否则循环体为空); - 变量作用域:局部变量(函数 / 块内定义)仅在作用域内有效,全局变量(函数外定义)整个程序有效;
- 类型匹配:赋值、函数参数传递时需保证类型匹配,避免隐式转换导致错误;
- 数组越界:访问数组时下标不能超出范围,否则会导致内存越界(程序崩溃);
- 指针空值:定义指针时建议初始化为
NULL(空指针),避免野指针。
总结
C 语言基础语法的核心是 “结构化”:通过变量 / 常量存储数据,运算符处理数据,流程控制组织执行逻辑,函数实现代码复用,数组 / 指针处理批量数据。掌握以上内容后,可进一步学习指针进阶、结构体、文件操作等内容,逐步构建完整的 C 语言知识体系。建议结合实例多写多练,通过调试理解语法细节,是掌握 C 语言的关键。
.
.
.


