Skip to content
← 返回C列表
知识专题

C 入门:编译、变量与类型 ​

从一个能运行的程序开始,再学习变量、分支、循环和函数。本文按 C11 的基础语法组织;后续学习指针和内存管理前,先完成末尾练习。

1. 编译并运行第一个程序 ​

需要可用的 C 编译器。下面使用 GCC;安装方式随操作系统而异,先用 gcc --version 确认命令可用。

将下面的代码保存为 hello.c:

c
#include <stdio.h>

int main(void)
{
    printf("Hello, World!\n");
    return 0;
}

stdio.h 声明标准输入输出函数。main 是程序入口,void 表示没有参数,return 0 表示正常结束。花括号组成代码块;声明和表达式语句通常以分号结束,代码块后不一律加分号。

在 Linux/macOS 的终端执行:

sh
gcc -std=c11 -Wall -Wextra hello.c -o hello
./hello

Windows 使用 GCC 时可输出 hello.exe,再在 PowerShell 中执行 ./hello.exe。编译失败时先读第一条错误;编译成功但不能启动时,再检查当前目录与可执行文件名。不要把终端提示符一起复制到命令里。

2. 声明变量与选择类型 ​

变量需要类型和名称。先初始化,再读取;不要依赖未初始化的局部变量。

c
int count = 3;
double price = 2.5;
char grade = 'A';
double total = count * price;
需求基础写法要确认的边界
整数计数int count = 3;类型范围由实现决定,不能假定所有整数类型都是同样大小
带小数的数值double price = 2.5;浮点数不能精确表示所有小数
一个字符char grade = 'A';单引号表示字符常量;字符编码另行考虑
一段字符串char name[] = "Ada";字符数组结尾包含 \0,不是独立的字符串基本类型
一组同类型数据int scores[3] = {80, 90, 100};下标只能使用 0 到 2
组合字段struct Point { int x; int y; };结构体成员各有自己的存储
共享存储表示不同成员union Value { int i; double d; };不能当成多个成员同时独立存值的结构体
一组具名整数常量enum State { STOPPED, RUNNING };枚举用于表达状态或有限选项
指向对象int *p = &count;解引用前必须确认指针有效、对象仍在生存期内
不返回值的函数void show(void);void 不等于可以声明一个普通空类型变量

同一个整数可以用不同进制写出:26、0x1A、032 都表示十进制26,前导 0 在这种整数字面量中表示八进制,不能把 032 当十进制32。通用转换方法和练习统一见进制与转换,这里不重复整张转换表。

这里先认识指针、结构体与联合体的用途,不在初学阶段展开动态内存管理。想看某个对象占用的字节数,使用 sizeof;不要把某台机器上的结果写成语言通则。

3. 分支、循环与函数 ​

if 根据条件选择分支;for 重复执行;函数给一段处理过程起名字,参数传入数据,返回值传回结果。

c
#include <stdio.h>

int sum(const int values[], int length)
{
    int total = 0;
    for (int i = 0; i < length; ++i) {
        total += values[i];
    }
    return total;
}

int main(void)
{
    int scores[] = {80, 90, 100};
    int total = sum(scores, 3);
    if (total >= 270) {
        printf("total=%d, passed\n", total);
    } else {
        printf("total=%d, retry\n", total);
    }
    return 0;
}

预期输出 total=270, passed。调用方把元素数量传给函数;数组形参不会自动携带数组长度,不能在 sum 中通过 sizeof(values) 推算原数组元素数。

4. 作用域、命名与注释 ​

示例中的 total 分别属于两个函数,各自独立。优先把变量放在使用它的最小作用域;需要共享数据时先通过参数传递,不必为了演示 extern 引入可变全局变量。

名称区分大小写,不能用关键字;业务名称尽量使用普通字母开头,避免占用实现保留的下划线名称。// 注释到行尾,/* ... */ 是块注释,块注释不能嵌套。

5. 练习与后续学习 ​

  1. 把数组改为四个成绩,更新传入的长度,确认总分正确。
  2. 将阈值作为函数参数传入,返回是否达标。
  3. 说明 count、&count 和 *p 分别表示什么。

完成后再学习字符串处理、指针与数组的关系、结构体和动态内存。数制基础可先读进制转换。

参考解法与预期(先完成练习)
  1. 使用 int scores[] = {80, 90, 100, 70}; 并传长度4,预期 total=340, passed。不能只增加元素却仍传3。
  2. 在 sum 定义之后、main 之前增加函数:
c
int meets_target(const int values[], int length, int target)
{
    return sum(values, length) >= target;
}

在 main 中用 meets_target(scores, 4, 340) 判断为真,阈值341为假;本练习只处理上面的少量成绩,不承诺任意整数求和都不溢出。 3. count 是整数值,&count 是该对象地址;当 p = &count 且对象仍存活时,*p 访问同一个整数。空指针不能解引用。

本文命令和新增答案仅作静态核对,示例未执行;首个程序的预期为 Hello, World! 后换行、退出0。

编译参数依据:GCC 总体选项。

继续阅读