
意义:防止程序运行过程中被意外修改,增强代码的稳定性、安全性和可读性。
#define MAX_SIZE 100。
全局变量与局部变量的区别,表面上是声明/定义的位置不同(函数内/外),但其本质是存储位置的不同,这直接导致了它们作用域和生命周期的天差地别。

程序运行时,数据主要存储在以下几个内存区域:
malloc, calloc, realloc)申请的空间。
free)。
static 静态变量、字符串常量等。
这是两个极易混淆但至关重要的概念:
重要关系:
static局部变量)。
学习感悟:讲到这,大多数人肯定感觉很懵,但请先别急,静下心来听完后面的内容,你就豁然开朗了。学习就是这样——“山重水复疑无路,柳暗花明又一村”。

关键字是C语言预先定义的、具有特殊含义的单词,我们不能用它们来命名变量或函数(如 int, if, return)。
数据类型是一种特殊的、用于声明变量和常量的关键字。它决定了:
int 通常占4字节)。
int 和 float 解释出来值不同)。
类比:数学中的数分为“常量”、“变量”,又可细分为整数、小数等。C语言的数据类型就是为计算机世界的“数”进行更精细的分类,如整型(
int)、字符型(char)、浮点型(float,double)。
注意:不同类型之间可以相互赋值,但可能会发生隐式类型转换,导致精度丢失或值改变(例如,将 float 赋给 int,小数部分会被截断)。
标识符就是给变量、函数、常量等起的名字,是我们在编程中的“命名”。
命名规则(必须遵守):
age 和 Age 是两个不同的变量)。
命名规范(良好习惯):
int student_age; VS. int a; (差)。
student_name (C语言常用)
tudentName
#define MAX_SIZE 100
为了理解字符型(char),必须引入ASCII编码的概念。
65 代表大写字母 'A')

扩展知识:
\开头,表示特殊字符
\n:换行符
\t:制表符
\\:反斜杠本身
\'、\":单引号、双引号
\0:空字符(字符串结束标志)
sizeof 与 strlen sizeof:
sizeof(array) 计算整个数组的大小。
strlen:
#include <string.h>,运行时才计算。
'\0'(字符串结束符)之前的字符个数。
strlen(string) 不包含结束符 '\0'。
关键区别:
char str[100] = "Hello";
printf("%zu", sizeof(str)); // 输出 100,计算的是数组的总容量
printf("%zu", strlen(str)); // 输出 5,计算的是字符串的实际长度#define 宏定义:#define PI 3.14159 // 注意:末尾没有分号!
#define MAX_N 100
#define GREETING "Hello, World!"PI 直接替换为 3.14159。
const 修饰变量:
const double pi = 3.14159;
const int max_n = 100;int age; // 定义了一个整型变量age(初值是随机的)
double salary;int count = 0; // 定义并初始化
char grade = 'A';=:表示将等号右边表达式的值存入等号左边变量所标识的内存空间中。count = 10; // 将10这个值放入count对应的内存中
grade = 'B'; // 将'B'的ASCII码值放入grade对应的内存中注意:" = " 是赋值,不是数学中的“等于”。数学中的等于是 " == "。
C语言通过标准库函数 scanf 和 printf 进行输入输出,它们通过格式控制字符串来指定数据的类型和格式。
printfprintf("格式控制字符串", 输出项列表);%d:以十进制输出 int
%c:输出 char
%f:输出 float/double
%lf:输出 double (推荐)
%s:输出字符串
%p:输出指针地址
%zu:输出 sizeof 的返回值类型 (size_t)
int a = 10;
char c = 'X';
double d = 3.14;
printf("a=%d, c=%c, d=%.2f\n", a, c, d);
// 输出:a=10, c=X, d=3.14scanf
scanf是一个不太安全的输入函数,因为它在写入时不会检查该
scanf("格式控制字符串", 变量地址列表);&)。
int age;
double height;
printf("请输入年龄和身高:");
scanf("%d %lf", &age, &height); // 注意:height是double,用%lf
printf("年龄:%d, 身高:%.2f\n", age, height);scanf 读取字符串时,变量是字符数组名(本身即地址),无需 &。char name[20];
scanf("%s", name); // 正确,name已是地址
// scanf("%s", &name); // 错误,&name写法多余且类型不匹配在C语言的格式化输入/输出中,
%m.n是极为重要的格式修饰符,它允许我们精确控制输入/输出的格式
%[flags][width][.precision]specifier其中:
flags:标志字符(如-, +, 0, #等)
width:指定最小字段宽度
.precision:指定精度(对于不同类型有不同含义)
specifier:类型说明符(如d, f, s等)
int num = 123;
printf("%5d", num); // 输出 " 123"(右对齐,宽度5)
printf("%-5d", num); // 输出 "123 "(左对齐,宽度5)
printf("%05d", num); // 输出 "00123"(用0填充)int width = 8;
printf("%*d", width, num); // 相当于 %8ddouble pi = 3.1415926535;
printf("%.2f", pi); // 输出 "3.14"(保留2位小数)
printf("%8.3f", pi); // 输出 " 3.142"(宽度8,保留3位小数)
printf("%.0f", pi); // 输出 "3"(不保留小数)char str[] = "HelloWorld";
printf("%.5s", str); // 输出 "Hello"(只输出前5个字符)
printf("%10.5s", str); // 输出 " Hello"(宽度10,只输出5字符)int num = 42;
printf("%.5d", num); // 输出 "00042"(至少5位,用0填充)
printf("%5.3d", num); // 输出 " 042"(宽度5,至少3位)int age;
float height;
char name[50];
// 基本输入
scanf("%d", &age); // 读取整数
scanf("%f", &height); // 读取浮点数
scanf("%s", name); // 读取字符串(不包含空格)
// 同时读取多个值
scanf("%d %f %s", &age, &height, name);char city[20];
// 限制最多读取19个字符(留一个位置给'\0')
scanf("%19s", city);
// 对于带有空格的字符串输入
char full_name[50];
scanf(" %49[^\n]", full_name); // 读取一行,最多49个字符char vowels[10];
// 只接收元音字母
scanf("%[aeiouAEIOU]", vowels);
// 排除某些字符
char no_digits[50];
scanf("%[^0-9]", no_digits); // 读取直到遇到数字
// 结合宽度限制
char limited[10];
scanf("%9[^\\n]", limited); // 最多读取9个非换行符int day, month, year;
// 输入格式: DD-MM-YYYY
scanf("%d-%d-%d", &day, &month, &year);
// 跳过不想要的输入
int important_value;
scanf("%*s %*s %d", &important_value); // 跳过前两个字符串,只读取第三个int num = 123;
printf("%-+10d", num); // 输出 "+123 "(左对齐,显示正负号)
printf("%#010x", num); // 输出 "0x0000007b"(显示0x前缀,用0填充).precision 在 scanf 中不起作用
width 表示最大读取宽度,而不是最小显示宽度
\0
结构体允许将多个不同类型的数据组合成一个单一的类型。
// 定义结构体类型
struct Student {
int id;
char name[50];
float score;
};
// 声明结构体变量
struct Student s1;
struct Student s2 = {1001, "张三", 95.5};
// 访问结构体成员
s1.id = 1002;
strcpy(s1.name, "李四");
s1.score = 88.5;
// 结构体指针
struct Student *ptr = &s1;
printf("学号:%d\n", ptr->id); // 使用->访问成员使用 typedef 为现有类型创建别名,简化复杂类型的声明。
// 为基本类型创建别名
typedef long long ll;
typedef long double ld;
// 为结构体创建别名
typedef struct {
int x;
int y;
} Point;
// 使用别名
ll count = 10;
Point p1 = {0, 0};强制类型转换允许显式地将一种数据类型转换为另一种类型。
(目标类型)表达式int a = 10, b = 3;
double result;
// 整数除法
result = a / b; // 3.0(整数除法)
result = (double)a / b; // 3.333...(强制转换后为浮点除法)
// 指针类型转换
int x = 100;
void *ptr = &x;
int *int_ptr = (int*)ptr; // 将void指针转换为int指针
// 字符与整数转换
char c = 'A';
int code = (int)c; // 65(ASCII码)1.精度丢失:大类型转小类型可能导致数据丢失
double d = 3.99;
int i = (int)d; // i = 3(小数部分被截断)2.符号问题:有符号与无符号类型转换需谨慎
int i = -1;
unsigned int u = (unsigned int)i; // 很大的正数3.指针转换:不同类型的指针转换可能导致未定义行为
内容总结:本节涵盖了C语言中数据的基础概念,从存储本质到具体使用,是理解程序如何运作的基石。后续内容将基于这些概念展开。