Appearance
基础语法
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;
}