开发环境#
任意文本编辑器以及 C 编译器。本文选择 gcc ↗ 在 Linux 上开发和调试。
安装 gcc#
使用包管理器安装 gcc。某些发行版可能已经自带 gcc。
# Debian / Ubuntu
sudo apt install gcc
# Redhat / CentOS / Fedora
sudo dnf install gcc
# Arch Linux / Manjaro
sudo pacman -S gccbash通过 Homebrew ↗ 安装。
brew install gccbash文本编辑器#
你可以使用任意文本编辑器,推荐 VSCode ↗。
Hello World#
创建 main.c 文件并编辑。
#include <stdio.h>
int main() {
printf("Hello, World!\n");
return 0;
}c编译代码,运行程序。
gcc main.c -o main
./main
# Hello, World!bashinclude 预处理指令#
在 C 语言中,以 # 开头的行是预处理器指令。#include <stdio.h> 告诉编译器:在编译之前先包含标准输入输出库(Standard Input Output)的信息,这样我们就可以使用 printf 等函数。
main 函数#
main 函数是程序的入口点。C 程序执行时,从这里开始。
int main() {
// 代码逻辑
return 0; // 程序结束,返回 0 表示成功
}c基本类型#
变量和类型#
变量是用于存储数据的容器,C 语言以以下的方式定义或声明变量。
int a = 10; // 定义并初始化为 10
int b; // 声明但不初始化,仅分配一块内存c常见的变量类型有:
int: 整数,如 10, -5,现代计算机上通常为 32 位float: 单精度浮点数,例如 3.14double: 双精度浮点数,精度更高char: 单个字符,例如 ‘A’, ‘z’
float 和 double 的区别在于精度,float 通常为 32 位,double 通常为 64 位。其二进制存储方式遵循 IEEE 754 标准 ↗,你可以在IEEE 754 Visualizer ↗直观地了解其存储原理。
#include <stdio.h>
int main() {
int a = 10;
double b = 3.14159;
char c = 'A';
// %d 格式化打印整数,%f 格式化打印浮点数,%c 格式化打印字符
printf("a = %d, b = %f, c = %c\n", a, b, c);
// a = 10, b = 3.141590, c = A
return 0;
}c更多基本类型信息可以参考 C 标准 ↗。
数组和字符串#
数组是存储多个相同类型数据的容器。C 语言中没有专门的字符串类型,而是使用字符数组。数组下标从 0 开始。
#include <stdio.h>
int main() {
int arr[5] = {1, 2, 3, 4, 5};
char str[] = "Hello";
printf("arr[2] = %d, str = %s\n", arr[2], str);
// arr[2] = 3, str = Hello
return 0;
}cC 语言规定字符串必须以空字符 \0(数值为零的字符)结尾。不像其他高级语言对字符串的封装,C 语言中的字符串只是一个 char[] 数组,程序并不能直接得到数组的长度(之后会提到为什么),因此通过遍历字符直到 \0 来确定字符串在哪里结束。
在定义 char str[] = "Hello"; 时,C 语言会自动在字符串末尾添加 \0,因此虽然只有 5 个字符,但 str 的长度为 6。
printf("%zu\n", sizeof(str));
// 6c如果字符串不以 \0 结尾,程序可能无法正确识别字符串的结束位置,继续连续遍历其后内存,导致未定义行为。
逻辑控制#
条件分支#
if ... else 根据条件执行不同的代码块。
int num = 10;
if (num > 0) {
printf("正数\n");
} else if (num < 0) {
printf("负数\n");
} else {
printf("零\n");
}c选择分支#
switch 用于多条件判断。
char grade = 'B';
switch (grade) {
case 'A':
printf("优秀\n");
break; // 跳出 switch,如果不加会继续向下执行
case 'B':
printf("良好\n");
break;
default:
printf("其他\n");
}c结构#
当我们知道循环次数时可以使用 for 循环。
for (int i = 0; i < 5; i++) {
printf("i = %d\n", i);
}c需要重复执行直到达成某个条件,不知道具体次数时,可以用 while 循环。
int i = 0;
while (i < 5) {
printf("i = %d\n", i);
++i;
}c函数#
函数是一组一起执行一个任务的语句。每个 C 程序都至少有一个函数,即 main 函数。
定义与调用#
函数由返回类型、函数名、参数列表和函数体组成。
#include <stdio.h>
// 函数定义:返回 int,接收两个 int 参数
int add(int x, int y) {
return x + y;
}
int main() {
int result = add(5, 3); // 函数调用
printf("result: %d\n", result);
return 0;
}c声明#
不同于其他语言,C 语言在调用函数时,该函数必须被声明过。尝试下面的示例,我们把 add 函数移动到 main 下方,代码就不能通过编译了。
#include <stdio.h>
int main() {
int result = add(5, 3); // 错误:隐式声明函数‘add’ [-Wimplicit-function-declaration]
printf("result: %d\n", result);
return 0;
}
int add(int x, int y) {
return x + y;
}c为了解决这个问题,我们可以在调用函数之前先声明函数。下面这个代码可以正常编译。
#include <stdio.h>
// 函数声明:不需要函数体,以分号结尾
int add(int x, int y);
int main() {
int result = add(5, 3);
printf("result: %d\n", result);
return 0;
}
// 函数定义
int add(int x, int y) {
return x + y;
}c下一章
继续学习指针和结构体...