Skip to content

C 语言基础语法

1. C 语言是什么

C 语言是一门经典的编程语言,特点是:

  • 运行效率高
  • 接近底层
  • 语法简洁
  • 适合学习程序设计基础
  • 广泛用于操作系统、嵌入式、驱动、编译器等领域

很多现代语言都受 C 语言影响。


2. 第一个 C 程序

c
#include <stdio.h>

int main(void)
{
    printf("Hello, C!\n");

    return 0;
}

输出:

text
Hello, C!

3. #include <stdio.h>

c
#include <stdio.h>

表示引入标准输入输出库。

因为:

c
printf()
scanf()

这些函数都定义在:

text
stdio.h

中。


4. main 函数

C 程序通常从:

c
main()

函数开始执行。

标准写法:

c
int main(void)
{
    return 0;
}

其中:

text
int

表示 main 最终返回一个整数。

c
return 0;

通常表示程序正常结束。


5. C 语言使用分号

C 语言中的大多数语句结尾需要:

text
;

例如:

c
int age = 18;
printf("%d\n", age);

如果忘记写分号,通常会编译报错。


6. 注释

单行注释:

c
// 这是单行注释

多行注释:

c
/*
这是
多行注释
*/

例如:

c
int age = 18;  // 用户年龄

变量

7. 什么是变量

变量用于保存数据。

例如:

c
int age = 18;

这里:

text
int

是数据类型。

text
age

是变量名。

text
18

是变量的值。


8. C 语言变量必须先声明类型

Python 可以:

python
age = 18

而 C 语言通常必须写:

c
int age = 18;

因为 C 是静态类型语言。


9. 常见基本数据类型

类型含义示例
char字符'A'
int整数100
float单精度浮点数3.14f
double双精度浮点数3.14

例如:

c
char grade = 'A';
int age = 18;
float height = 1.75f;
double pi = 3.1415926;

10. char

char 用于保存单个字符。

例如:

c
char ch = 'A';

注意字符使用:

text
单引号

例如:

c
'A'

而:

c
"A"

是字符串,不是单个字符。


11. int

int 用于保存整数。

例如:

c
int age = 18;
int score = 100;
int number = -10;

12. float

c
float price = 19.99f;

通常建议在浮点常量后写:

text
f

表示这是 float


13. double

c
double pi = 3.1415926535;

double 通常比 float 精度更高。


14. sizeof

可以使用:

c
sizeof

查看类型或变量占多少字节。

例如:

c
printf("%zu\n", sizeof(int));

也可以:

c
int age = 18;

printf("%zu\n", sizeof(age));

不同平台的具体大小可能有所差异。


输出

15. printf

C 语言最常用的输出函数:

c
printf()

例如:

c
printf("Hello\n");

16. 格式化输出

输出整数:

c
int age = 18;

printf("%d\n", age);

其中:

text
%d

表示输出十进制整数。


17. 常见格式说明符

格式用途
%dint
%cchar
%f浮点数
%s字符串
%u无符号整数
%ldlong
%p地址

例如:

c
char grade = 'A';
int age = 18;
double height = 1.75;

printf("%c\n", grade);
printf("%d\n", age);
printf("%f\n", height);

18. 一次输出多个变量

c
int age = 18;
double height = 1.75;

printf("age = %d, height = %.2f\n", age, height);

其中:

text
%.2f

表示保留两位小数。


19. 转义字符

常见:

转义字符作用
\n换行
\t制表符
\"双引号
\\反斜杠

例如:

c
printf("Hello\nWorld\n");

输出:

text
Hello
World

输入

20. scanf

C 语言常用:

c
scanf()

获取输入。

例如:

c
int age;

scanf("%d", &age);

输入:

text
18

那么:

text
age

就会保存:

text
18

21. 为什么 scanf 里有 &

例如:

c
scanf("%d", &age);

这里:

text
&age

表示:

text
age 的内存地址

scanf 需要知道把输入的数据写到哪里,所以需要变量地址。

这是 C 语言中指针概念的基础。


22. 输入多个值

c
int a;
int b;

scanf("%d %d", &a, &b);

例如输入:

text
10 20

那么:

text
a = 10
b = 20

常量

23. const

如果变量初始化之后不希望修改:

c
const int MAX = 100;

之后不能正常写:

c
MAX = 200;

24. 宏常量

也可以:

c
#define PI 3.1415926

例如:

c
#include <stdio.h>

#define PI 3.1415926

int main(void)
{
    printf("%f\n", PI);

    return 0;
}

运算符

25. 算术运算符

运算符含义
+
-
*
/
%取余

例如:

c
int a = 10;
int b = 3;

printf("%d\n", a + b);
printf("%d\n", a - b);
printf("%d\n", a * b);
printf("%d\n", a / b);
printf("%d\n", a % b);

26. 整数除法

如果两个操作数都是整数:

c
int a = 10;
int b = 3;

printf("%d\n", a / b);

输出:

text
3

小数部分会被丢弃。


27. 浮点除法

如果希望得到:

text
3.333...

可以:

c
double result = 10.0 / 3.0;

或者:

c
double result = (double)10 / 3;

28. 取余 %

c
int result = 10 % 3;

结果:

text
1

常用于:

text
判断奇偶
循环处理
取个位数

例如判断偶数:

c
if (number % 2 == 0)
{
    printf("偶数\n");
}

29. 自增和自减

c
i++;

表示:

c
i = i + 1;

自减:

c
i--;

表示:

c
i = i - 1;

比较运算

30. 比较运算符

运算符含义
==等于
!=不等于
>大于
<小于
>=大于等于
<=小于等于

例如:

c
int age = 18;

printf("%d\n", age >= 18);

条件成立时通常得到:

text
1

不成立通常得到:

text
0

31. ===

一定不要混淆。

c
a = 10;

表示:

text
赋值

而:

c
a == 10

表示:

text
判断是否相等

逻辑运算

32. 逻辑运算符

运算符含义
&&
`
!

例如:

c
if (age >= 18 && age <= 60)
{
    printf("满足条件\n");
}

33. &&

两个条件都成立:

c
a > 0 && b > 0

结果才成立。


34. ||

只要有一个条件成立:

c
a > 0 || b > 0

结果就成立。


35. !

取反:

c
!condition

例如:

c
if (!is_ok)
{
    printf("条件不成立\n");
}

条件判断

36. if

基本结构:

c
if (条件)
{
    代码;
}

例如:

c
int age = 20;

if (age >= 18)
{
    printf("成年人\n");
}

37. if...else

c
if (age >= 18)
{
    printf("成年人\n");
}
else
{
    printf("未成年人\n");
}

38. if...else if...else

c
int score = 85;

if (score >= 90)
{
    printf("优秀\n");
}
else if (score >= 80)
{
    printf("良好\n");
}
else if (score >= 60)
{
    printf("及格\n");
}
else
{
    printf("不及格\n");
}

39. 花括号

C 语言使用:

text
{}

表示代码块。

例如:

c
if (age >= 18)
{
    printf("成年人\n");
    printf("条件成立\n");
}

switch

40. switch

当一个变量需要和多个固定值比较时,可以使用:

c
switch

例如:

c
int choice = 2;

switch (choice)
{
    case 1:
        printf("选项 1\n");
        break;

    case 2:
        printf("选项 2\n");
        break;

    case 3:
        printf("选项 3\n");
        break;

    default:
        printf("无效选项\n");
}

41. break

switch 中:

c
break;

用于结束当前分支。

如果忘记:

c
break;

程序可能继续执行后面的 case


循环

42. for 循环

基本结构:

c
for (初始化; 条件; 更新)
{
    代码;
}

例如:

c
for (int i = 0; i < 5; i++)
{
    printf("%d\n", i);
}

输出:

text
0
1
2
3
4

43. for 的执行过程

c
for (int i = 0; i < 5; i++)

可以拆成:

text
1. int i = 0
2. 判断 i < 5
3. 执行循环体
4. i++
5. 再判断 i < 5

不断重复。


44. while

基本结构:

c
while (条件)
{
    代码;
}

例如:

c
int i = 0;

while (i < 5)
{
    printf("%d\n", i);
    i++;
}

45. do...while

c
do
{
    代码;
}
while (条件);

例如:

c
int i = 0;

do
{
    printf("%d\n", i);
    i++;
}
while (i < 5);

特点:

text
循环体至少执行一次

46. break

break 可以提前退出循环。

例如:

c
for (int i = 0; i < 10; i++)
{
    if (i == 5)
    {
        break;
    }

    printf("%d\n", i);
}

输出:

text
0
1
2
3
4

47. continue

continue 跳过本次循环剩余代码。

例如:

c
for (int i = 0; i < 5; i++)
{
    if (i == 2)
    {
        continue;
    }

    printf("%d\n", i);
}

输出:

text
0
1
3
4

数组

48. 一维数组

数组可以保存多个相同类型的数据。

例如:

c
int numbers[5] = {10, 20, 30, 40, 50};

数组长度:

text
5

49. 数组下标

C 数组下标从:

text
0

开始。

例如:

text
numbers[0] = 10
numbers[1] = 20
numbers[2] = 30

访问:

c
printf("%d\n", numbers[0]);

50. 修改数组元素

c
numbers[0] = 100;

修改后:

text
第一个元素变成 100

51. 遍历数组

c
int numbers[5] = {10, 20, 30, 40, 50};

for (int i = 0; i < 5; i++)
{
    printf("%d\n", numbers[i]);
}

52. 计算数组长度

可以:

c
int numbers[] = {10, 20, 30, 40, 50};

int length = sizeof(numbers) / sizeof(numbers[0]);

结果:

text
5

常见写法:

c
for (int i = 0; i < sizeof(numbers) / sizeof(numbers[0]); i++)
{
    printf("%d\n", numbers[i]);
}

字符串

53. C 语言字符串

C 语言没有独立的基础字符串类型。

字符串本质上是:

text
char 数组

例如:

c
char name[] = "Tom";

实际类似:

text
'T' 'o' 'm' '\0'

最后会有:

text
\0

表示字符串结束。


54. 输出字符串

c
char name[] = "Tom";

printf("%s\n", name);

其中:

text
%s

表示字符串。


55. 字符串和字符

字符:

c
char ch = 'A';

使用:

text
单引号

字符串:

c
char text[] = "A";

使用:

text
双引号

二者完全不同。


56. string.h

处理字符串时经常需要:

c
#include <string.h>

常见函数:

text
strlen
strcmp
strcpy
strcat

57. strlen

获取字符串长度:

c
#include <stdio.h>
#include <string.h>

int main(void)
{
    char text[] = "Hello";

    printf("%zu\n", strlen(text));

    return 0;
}

输出:

text
5

58. strcmp

比较两个字符串:

c
strcmp(a, b)

不能直接用:

c
a == b

比较字符串内容。

例如:

c
if (strcmp(name, "Tom") == 0)
{
    printf("相等\n");
}

函数

59. 定义函数

例如:

c
void hello(void)
{
    printf("Hello\n");
}

调用:

c
hello();

60. 带参数的函数

c
void hello(char name[])
{
    printf("Hello, %s\n", name);
}

调用:

c
hello("Tom");

61. 有返回值的函数

c
int add(int a, int b)
{
    return a + b;
}

调用:

c
int result = add(10, 20);

printf("%d\n", result);

输出:

text
30

62. 函数声明

如果函数定义写在 main 后面,通常需要提前声明。

例如:

c
#include <stdio.h>

int add(int a, int b);

int main(void)
{
    int result = add(10, 20);

    printf("%d\n", result);

    return 0;
}

int add(int a, int b)
{
    return a + b;
}

这里:

c
int add(int a, int b);

就是函数声明。


作用域

63. 局部变量

函数内部声明的变量通常是局部变量。

例如:

c
void test(void)
{
    int number = 10;
}

number 通常只能在:

text
test

函数内部使用。


64. 全局变量

定义在函数外:

c
int number = 10;

int main(void)
{
    printf("%d\n", number);

    return 0;
}

这样的变量属于:

text
全局变量

一般不建议无节制使用全局变量。


指针基础

65. 地址

每个变量在内存中都有一个地址。

例如:

c
int number = 10;

可以:

c
printf("%p\n", (void *)&number);

其中:

text
&

表示:

text
取地址

66. 指针

指针是:

text
保存内存地址的变量

例如:

c
int number = 10;

int *p = &number;

这里:

text
p

保存:

text
number 的地址

67. * 解引用

c
printf("%d\n", *p);

表示:

text
访问 p 指向地址中的值

输出:

text
10

可以简单记:

text
&变量
获取地址

*指针
访问这个地址里的值

68. 修改指针指向的数据

c
int number = 10;
int *p = &number;

*p = 20;

此时:

text
number

也变成:

text
20

结构体

69. struct

结构体可以把多个不同类型的数据组合起来。

例如:

c
struct Student
{
    char name[20];
    int age;
    double score;
};

创建变量:

c
struct Student student;

70. 访问结构体成员

c
student.age = 18;
student.score = 90.5;

使用:

text
.

访问成员。

例如:

c
printf("%d\n", student.age);

71. 初始化结构体

c
struct Student
{
    char name[20];
    int age;
};

int main(void)
{
    struct Student student = {"Tom", 18};

    printf("%s %d\n", student.name, student.age);

    return 0;
}

类型转换

72. 自动类型转换

例如:

c
int a = 10;
double b = a;

C 会自动把:

text
10

转换为:

text
10.0

73. 强制类型转换

格式:

c
(类型)变量

例如:

c
int a = 10;
int b = 3;

double result = (double)a / b;

结果:

text
3.333...

枚举

74. enum

枚举可以给一组整数常量起名字。

例如:

c
enum Day
{
    MONDAY,
    TUESDAY,
    WEDNESDAY
};

默认:

text
MONDAY = 0
TUESDAY = 1
WEDNESDAY = 2

typedef

75. 类型别名

例如:

c
typedef unsigned int uint;

以后可以:

c
uint age = 18;

76. 结构体配合 typedef

常见写法:

c
typedef struct
{
    char name[20];
    int age;
} Student;

之后:

c
Student student;

不需要每次都写:

c
struct Student

文件基本结构

77. 一个普通 C 程序

c
#include <stdio.h>

int add(int a, int b);

int main(void)
{
    int a = 10;
    int b = 20;

    int result = add(a, b);

    printf("%d\n", result);

    return 0;
}

int add(int a, int b)
{
    return a + b;
}

可以看到:

text
头文件
函数声明
main 函数
其他函数

编译和运行

78. C 代码需要编译

Python 可以直接:

bash
python main.py

C 通常需要先:

text
源代码

编译器

可执行文件

79. 使用 GCC 编译

假设文件:

text
main.c

编译:

bash
gcc main.c -o main

运行:

bash
./main

80. 使用 Clang 编译

macOS 常见:

bash
clang main.c -o main

然后:

bash
./main

81. 推荐打开警告

学习 C 时推荐:

bash
gcc -Wall -Wextra main.c -o main

或者:

bash
clang -Wall -Wextra main.c -o main

这样编译器会帮你发现更多潜在问题。


常见基础练习

82. 判断奇偶数

c
#include <stdio.h>

int main(void)
{
    int number;

    scanf("%d", &number);

    if (number % 2 == 0)
    {
        printf("偶数\n");
    }
    else
    {
        printf("奇数\n");
    }

    return 0;
}

83. 求 1 到 100 的和

c
#include <stdio.h>

int main(void)
{
    int sum = 0;

    for (int i = 1; i <= 100; i++)
    {
        sum += i;
    }

    printf("%d\n", sum);

    return 0;
}

84. 找最大值

c
#include <stdio.h>

int main(void)
{
    int a;
    int b;

    scanf("%d %d", &a, &b);

    if (a > b)
    {
        printf("%d\n", a);
    }
    else
    {
        printf("%d\n", b);
    }

    return 0;
}

85. 最大公约数

使用辗转相除法:

c
#include <stdio.h>

int main(void)
{
    int a;
    int b;

    scanf("%d %d", &a, &b);

    while (b != 0)
    {
        int temp = a % b;
        a = b;
        b = temp;
    }

    printf("%d\n", a);

    return 0;
}

86. 冒泡排序

c
#include <stdio.h>

int main(void)
{
    int numbers[] = {5, 3, 8, 1, 2};
    int length = sizeof(numbers) / sizeof(numbers[0]);

    for (int i = 0; i < length - 1; i++)
    {
        for (int j = 0; j < length - 1 - i; j++)
        {
            if (numbers[j] > numbers[j + 1])
            {
                int temp = numbers[j];
                numbers[j] = numbers[j + 1];
                numbers[j + 1] = temp;
            }
        }
    }

    for (int i = 0; i < length; i++)
    {
        printf("%d ", numbers[i]);
    }

    printf("\n");

    return 0;
}

易错点

87. ===

错误:

c
if (a = 10)

这表示赋值。

判断相等应该写:

c
if (a == 10)

88. 数组越界

例如:

c
int numbers[5];

合法下标:

text
0
1
2
3
4

访问:

c
numbers[5]

属于越界。

C 语言通常不会自动帮你检查数组边界,所以要特别小心。


89. 未初始化变量

例如:

c
int number;

printf("%d\n", number);

number 没有初始化,它的值是不确定的。

更推荐:

c
int number = 0;

90. 整数除法

c
int result = 5 / 2;

结果:

text
2

不是:

text
2.5

如果需要小数:

c
double result = 5.0 / 2;

91. 字符串不能直接用 ==

例如:

c
char name[] = "Tom";

不要用:

c
name == "Tom"

比较字符串内容。

应该使用:

c
strcmp(name, "Tom") == 0

92. scanf 忘记 &

整数输入:

c
scanf("%d", &age);

而不是:

c
scanf("%d", age);

因为 scanf 需要变量地址。


93. % 只能用于整数

例如:

c
10 % 3

可以。

但是普通 % 运算符不能直接用于浮点数。


基础语法速查

94. 变量

c
int age = 18;
double height = 1.75;
char grade = 'A';

95. 输出

c
printf("%d\n", age);

96. 输入

c
scanf("%d", &age);

97. 判断

c
if (age >= 18)
{
    printf("成年人\n");
}
else
{
    printf("未成年人\n");
}

98. for

c
for (int i = 0; i < 10; i++)
{
    printf("%d\n", i);
}

99. while

c
while (condition)
{
    // ...
}

100. 数组

c
int numbers[] = {1, 2, 3, 4, 5};

101. 字符串

c
char text[] = "Hello";

102. 函数

c
int add(int a, int b)
{
    return a + b;
}

103. 指针

c
int number = 10;
int *p = &number;

知识结构

104. C 语言基础学习顺序

建议按照下面的顺序学习:

text
C 语言基础
├── 程序结构
├── 变量与数据类型
├── 输入输出
├── 运算符
├── if / switch
├── for / while
├── 数组
├── 字符串
├── 函数
├── 指针
├── 结构体
└── 文件操作

其中最重要的基础部分是:

text
变量
判断
循环
数组
函数
指针

小结

C 语言最基础的程序结构:

c
#include <stdio.h>

int main(void)
{
    printf("Hello, C!\n");

    return 0;
}

入门阶段最需要掌握:

text
变量与数据类型
printf / scanf
运算符
if / else
switch
for / while
数组
字符串
函数

之后重点进入 C 语言真正核心的内容:

text
指针
数组与指针
字符串与指针
结构体
动态内存
文件操作

其中尤其重要的是:

text
数组从 0 开始

= 是赋值
== 是比较

scanf 通常需要变量地址

整数 / 整数仍然是整数除法

字符串本质上是 char 数组

指针保存的是内存地址

把这些基础语法真正写熟之后,再学习指针和内存管理会容易很多。