Skip to content

基础语法

C 语言是一种通用的、过程式的编程语言,由 Dennis Ritchie 于 1972 年在贝尔实验室开发。

第一个 C 程序

c
#include <stdio.h>

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

// 编译: gcc hello.c -o hello
// 运行: ./hello

数据类型

基本数据类型

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

int main() {
    // 整数类型
    char c = 'A';           // 1 字节
    short s = 100;          // 2 字节
    int i = 1000;           // 4 字节(常用)
    long l = 100000L;       // 4 或 8 字节
    long long ll = 10000000000LL;  // 8 字节

    // 无符号整数
    unsigned int ui = 4000000000U;
    unsigned long ul = 4000000000UL;

    // 浮点类型
    float f = 3.14f;        // 4 字节
    double d = 3.141592653; // 8 字节(常用)
    long double ld = 3.14159265358979L;

    // 打印各类型大小
    printf("char: %zu bytes\n", sizeof(char));
    printf("short: %zu bytes\n", sizeof(short));
    printf("int: %zu bytes\n", sizeof(int));
    printf("long: %zu bytes\n", sizeof(long));
    printf("long long: %zu bytes\n", sizeof(long long));
    printf("float: %zu bytes\n", sizeof(float));
    printf("double: %zu bytes\n", sizeof(double));

    return 0;
}

类型范围

c
#include <stdio.h>
#include <limits.h>
#include <float.h>

int main() {
    printf("int 范围: %d%d\n", INT_MIN, INT_MAX);
    printf("char 范围: %d%d\n", CHAR_MIN, CHAR_MAX);
    printf("short 范围: %d%d\n", SHRT_MIN, SHRT_MAX);
    printf("long 范围: %ld%ld\n", LONG_MIN, LONG_MAX);

    printf("float 范围: %e%e\n", FLT_MIN, FLT_MAX);
    printf("double 范围: %e%e\n", DBL_MIN, DBL_MAX);

    return 0;
}

变量

变量声明与初始化

c
#include <stdio.h>

int global_var = 100;  // 全局变量

int main() {
    // 声明并初始化
    int a = 10;
    float b = 3.14f;
    char c = 'A';

    // 先声明后赋值
    int d;
    d = 20;

    // 同时声明多个变量
    int x = 1, y = 2, z = 3;

    // 常量
    const int MAX_SIZE = 100;
    // MAX_SIZE = 200;  // 错误:不能修改常量

    // 使用 #define 定义常量
    #define PI 3.14159
    printf("PI = %f\n", PI);

    printf("a = %d, b = %f, c = %c\n", a, b, c);

    return 0;
}

变量作用域

c
#include <stdio.h>

int global = 100;  // 全局变量

void func() {
    int local = 200;  // 局部变量
    printf("局部变量: %d\n", local);
    printf("全局变量: %d\n", global);
}

int main() {
    int local = 300;  // main 函数的局部变量

    {
        int block_var = 400;  // 块级变量
        printf("块级变量: %d\n", block_var);
    }
    // block_var 在这里不可访问

    func();
    printf("main 局部变量: %d\n", local);

    return 0;
}

运算符

算术运算符

c
#include <stdio.h>

int main() {
    int a = 10, b = 3;

    printf("a + b = %d\n", a + b);   // 13 加
    printf("a - b = %d\n", a - b);   // 7  减
    printf("a * b = %d\n", a * b);   // 30 乘
    printf("a / b = %d\n", a / b);   // 3  整除
    printf("a %% b = %d\n", a % b);  // 1  取余

    // 自增自减
    int x = 5;
    printf("x++ = %d\n", x++);  // 5(先返回后加)
    printf("x = %d\n", x);      // 6
    printf("++x = %d\n", ++x);  // 7(先加后返回)

    // 浮点除法
    float f1 = 10.0f, f2 = 3.0f;
    printf("10.0 / 3.0 = %f\n", f1 / f2);  // 3.333...

    return 0;
}

关系运算符

c
#include <stdio.h>

int main() {
    int a = 5, b = 10;

    printf("a == b: %d\n", a == b);  // 0 (false)
    printf("a != b: %d\n", a != b);  // 1 (true)
    printf("a > b: %d\n", a > b);    // 0
    printf("a < b: %d\n", a < b);    // 1
    printf("a >= b: %d\n", a >= b);  // 0
    printf("a <= b: %d\n", a <= b);  // 1

    return 0;
}

逻辑运算符

c
#include <stdio.h>
#include <stdbool.h>  // C99 引入的布尔类型

int main() {
    bool a = true, b = false;

    printf("a && b: %d\n", a && b);  // 0 与
    printf("a || b: %d\n", a || b);  // 1 或
    printf("!a: %d\n", !a);          // 0 非

    // 短路求值
    int x = 0;
    if (x != 0 && 10 / x > 1) {
        // 不会执行,因为短路
    }

    return 0;
}

位运算符

c
#include <stdio.h>

int main() {
    unsigned int a = 5;   // 0101
    unsigned int b = 3;   // 0011

    printf("a & b = %u\n", a & b);    // 1  (0001) 按位与
    printf("a | b = %u\n", a | b);    // 7  (0111) 按位或
    printf("a ^ b = %u\n", a ^ b);    // 6  (0110) 按位异或
    printf("~a = %u\n", ~a);          // 按位取反
    printf("a << 1 = %u\n", a << 1);  // 10 (1010) 左移
    printf("a >> 1 = %u\n", a >> 1);  // 2  (0010) 右移

    return 0;
}

三元运算符

c
#include <stdio.h>

int main() {
    int age = 18;
    char *status = (age >= 18) ? "成年" : "未成年";
    printf("状态: %s\n", status);

    // 嵌套
    int score = 85;
    char *grade = (score >= 90) ? "A" :
                  (score >= 80) ? "B" :
                  (score >= 60) ? "C" : "D";
    printf("等级: %s\n", grade);

    return 0;
}

控制流程

条件语句

c
#include <stdio.h>

int main() {
    int score = 85;

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

    // switch
    int day = 3;
    switch (day) {
        case 1:
            printf("星期一\n");
            break;
        case 2:
            printf("星期二\n");
            break;
        case 3:
            printf("星期三\n");
            break;
        default:
            printf("其他\n");
    }

    return 0;
}

循环语句

c
#include <stdio.h>

int main() {
    // for 循环
    printf("for 循环:\n");
    for (int i = 0; i < 5; i++) {
        printf("%d ", i);
    }
    printf("\n");

    // while 循环
    printf("while 循环:\n");
    int j = 0;
    while (j < 5) {
        printf("%d ", j);
        j++;
    }
    printf("\n");

    // do-while 循环
    printf("do-while 循环:\n");
    int k = 0;
    do {
        printf("%d ", k);
        k++;
    } while (k < 5);
    printf("\n");

    // break 和 continue
    printf("break 示例:\n");
    for (int i = 0; i < 10; i++) {
        if (i == 5) break;
        printf("%d ", i);
    }
    printf("\n");

    printf("continue 示例:\n");
    for (int i = 0; i < 10; i++) {
        if (i % 2 == 0) continue;
        printf("%d ", i);
    }
    printf("\n");

    return 0;
}

输入输出

printf 格式化输出

c
#include <stdio.h>

int main() {
    int i = 42;
    float f = 3.14159f;
    double d = 3.141592653;
    char c = 'A';
    char str[] = "Hello";

    // 基本格式
    printf("整数: %d\n", i);
    printf("浮点: %f\n", f);
    printf("字符: %c\n", c);
    printf("字符串: %s\n", str);

    // 宽度和精度
    printf("宽度10: %10d\n", i);      // 右对齐
    printf("左对齐: %-10d|\n", i);    // 左对齐
    printf("精度2: %.2f\n", f);       // 小数点后2位
    printf("宽度和精度: %10.2f\n", f);

    // 不同进制
    printf("八进制: %o\n", i);
    printf("十六进制: %x\n", i);
    printf("十六进制(大写): %X\n", i);

    // 长度修饰符
    long l = 100000L;
    printf("long: %ld\n", l);
    printf("long long: %lld\n", (long long)l);

    // 指针
    int *p = &i;
    printf("指针地址: %p\n", (void*)p);

    // %% 打印百分号
    printf("百分比: 100%%\n");

    return 0;
}

scanf 格式化输入

c
#include <stdio.h>

int main() {
    int age;
    float height;
    char name[50];

    printf("请输入姓名: ");
    scanf("%s", name);  // 不需要 &,数组名就是地址

    printf("请输入年龄: ");
    scanf("%d", &age);  // 需要 &

    printf("请输入身高: ");
    scanf("%f", &height);

    printf("\n姓名: %s\n", name);
    printf("年龄: %d\n", age);
    printf("身高: %.2f\n", height);

    // 读取字符(包括空格)
    char buffer[100];
    printf("请输入一行文字: ");
    getchar();  // 消耗之前的换行符
    fgets(buffer, sizeof(buffer), stdin);
    printf("你输入的是: %s", buffer);

    return 0;
}

字符输入输出

c
#include <stdio.h>

int main() {
    char c;

    // getchar 和 putchar
    printf("请输入一个字符: ");
    c = getchar();
    printf("你输入的字符是: ");
    putchar(c);
    putchar('\n');

    // getch (非标准,需要 conio.h)
    // printf("按任意键继续...\n");
    // getch();

    // 读取直到换行
    printf("请输入一行字符:\n");
    while ((c = getchar()) != '\n' && c != EOF) {
        putchar(c);
    }
    putchar('\n');

    return 0;
}

类型转换

隐式类型转换

c
#include <stdio.h>

int main() {
    // 自动类型提升
    int i = 5;
    float f = 2.5f;
    float result = i + f;  // int 提升为 float
    printf("result = %f\n", result);  // 7.5

    // 赋值时的类型转换
    double d = 3.14159;
    int j = d;  // 截断小数部分
    printf("j = %d\n", j);  // 3

    return 0;
}

显式类型转换

c
#include <stdio.h>

int main() {
    int a = 5, b = 2;

    // 整数除法
    printf("a / b = %d\n", a / b);  // 2

    // 强制类型转换
    printf("(float)a / b = %f\n", (float)a / b);  // 2.5

    // 指针类型转换
    int i = 65;
    char *p = (char*)&i;
    printf("第一个字节: %c\n", *p);  // A

    // void 指针
    void *vp = &a;
    int *ip = (int*)vp;
    printf("值: %d\n", *ip);

    return 0;
}

存储类

auto、static、extern、register

c
#include <stdio.h>

// extern 声明外部变量
extern int external_var;

// 全局变量
int global_var = 100;

void counter() {
    // static 变量只初始化一次
    static int count = 0;
    count++;
    printf("调用次数: %d\n", count);
}

int main() {
    // auto 是默认的局部变量存储类
    auto int local = 10;

    // register 建议编译器将变量存储在寄存器中
    register int fast_var = 20;

    // static 局部变量
    counter();  // 调用次数: 1
    counter();  // 调用次数: 2
    counter();  // 调用次数: 3

    printf("local = %d\n", local);
    printf("fast_var = %d\n", fast_var);
    printf("global_var = %d\n", global_var);

    return 0;
}

实践示例

计算器程序

c
#include <stdio.h>

int add(int a, int b) { return a + b; }
int subtract(int a, int b) { return a - b; }
int multiply(int a, int b) { return a * b; }
int divide(int a, int b) { return b != 0 ? a / b : 0; }

int main() {
    int a, b;
    char op;

    printf("简单计算器\n");
    printf("输入格式: 数字 运算符 数字 (例如: 5 + 3)\n");
    printf("请输入: ");
    scanf("%d %c %d", &a, &op, &b);

    int result;
    switch (op) {
        case '+': result = add(a, b); break;
        case '-': result = subtract(a, b); break;
        case '*': result = multiply(a, b); break;
        case '/':
            if (b == 0) {
                printf("错误: 除数不能为0\n");
                return 1;
            }
            result = divide(a, b);
            break;
        default:
            printf("错误: 不支持的运算符\n");
            return 1;
    }

    printf("结果: %d %c %d = %d\n", a, op, b, result);

    return 0;
}

猜数字游戏

c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    int number, guess, attempts = 0;

    // 设置随机种子
    srand(time(NULL));
    number = rand() % 100 + 1;  // 1-100 的随机数

    printf("猜数字游戏 (1-100)\n");
    printf("我已经想好了一个数字,请猜猜看!\n\n");

    do {
        printf("请输入你的猜测: ");
        scanf("%d", &guess);
        attempts++;

        if (guess > number) {
            printf("太大了!\n");
        } else if (guess < number) {
            printf("太小了!\n");
        } else {
            printf("\n恭喜你猜对了!\n");
            printf("答案是: %d\n", number);
            printf("你用了 %d 次猜中!\n", attempts);
        }
    } while (guess != number);

    return 0;
}

成绩管理系统

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

#define MAX_STUDENTS 100

typedef struct {
    char name[50];
    int id;
    float score;
} Student;

int main() {
    Student students[MAX_STUDENTS];
    int count = 0;
    int choice;

    while (1) {
        printf("\n===== 学生成绩管理系统 =====\n");
        printf("1. 添加学生\n");
        printf("2. 显示所有学生\n");
        printf("3. 查找学生\n");
        printf("4. 统计信息\n");
        printf("5. 退出\n");
        printf("请选择: ");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                if (count >= MAX_STUDENTS) {
                    printf("学生数量已达上限!\n");
                    break;
                }
                printf("请输入姓名: ");
                scanf("%s", students[count].name);
                printf("请输入学号: ");
                scanf("%d", &students[count].id);
                printf("请输入成绩: ");
                scanf("%f", &students[count].score);
                count++;
                printf("添加成功!\n");
                break;

            case 2:
                printf("\n%-10s %-10s %-10s\n", "姓名", "学号", "成绩");
                printf("--------------------------\n");
                for (int i = 0; i < count; i++) {
                    printf("%-10s %-10d %-10.2f\n",
                           students[i].name,
                           students[i].id,
                           students[i].score);
                }
                break;

            case 3: {
                int search_id;
                printf("请输入学号: ");
                scanf("%d", &search_id);
                int found = 0;
                for (int i = 0; i < count; i++) {
                    if (students[i].id == search_id) {
                        printf("找到学生: %s, 成绩: %.2f\n",
                               students[i].name, students[i].score);
                        found = 1;
                        break;
                    }
                }
                if (!found) {
                    printf("未找到该学生!\n");
                }
                break;
            }

            case 4:
                if (count == 0) {
                    printf("暂无学生数据!\n");
                    break;
                }
                float total = 0, max = students[0].score, min = students[0].score;
                for (int i = 0; i < count; i++) {
                    total += students[i].score;
                    if (students[i].score > max) max = students[i].score;
                    if (students[i].score < min) min = students[i].score;
                }
                printf("\n学生人数: %d\n", count);
                printf("平均成绩: %.2f\n", total / count);
                printf("最高成绩: %.2f\n", max);
                printf("最低成绩: %.2f\n", min);
                break;

            case 5:
                printf("再见!\n");
                return 0;

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

    return 0;
}