C语言指针与结构体 - 课堂笔记
一、值传递 vs 地址传递
1. 值传递(传值)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include <stdio.h>
void f(int p) { p = 100; }
int main() { int i = 88; printf("i=%d\n", i); f(i); printf("i=%d\n", i); }
|
特点:函数内部修改不影响外部变量
2. 地址传递(传址)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| #include <stdio.h>
void f(int *p) { *p = 100; }
int main() { int i = 88; printf("i=%d\n", i); f(&i); printf("i=%d\n", i); }
|
特点:通过指针直接修改外部变量
二、数组与指针
1. 数组的三种遍历方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| #include <stdio.h>
int main() { int a[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; i++) printf("%d\n", a[i]);
for (int i = 0; i < 5; i++) printf("%d\n", *(a + i));
int *p = a; for (int i = 0; i < 5; i++) printf("%d\n", *(p + i)); }
|
2. 关键知识点
| 表达式 |
含义 |
a |
数组名,表示首元素地址 |
*a |
首元素的值 a[0] |
a + i |
第 i 个元素的地址 |
*(a + i) |
第 i 个元素的值 a[i] |
p + i |
与 a + i 等价 |
三、结构体
1. 结构体的定义
1 2 3 4 5 6
| struct Student { int sid; char name[200]; int age; };
|
2. 结构体变量的定义与初始化
1
| struct Student st = {1000, "zhangsan", 20};
|
3. 访问结构体成员的三种方式
1 2 3 4 5 6 7 8 9 10 11
| struct Student st = {1000, "zhangsan", 20}; struct Student *pst = &st;
st.sid = 99;
(*pst).sid = 99;
pst->sid = 99;
|
4. 结构体指针作为函数参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| #include <stdio.h> #include <string.h>
struct Student { int sid; char name[200]; int age; };
void f(struct Student *pst) { pst->sid = 1000; strcpy(pst->name, "zhangsan"); pst->age = 20; }
void g(struct Student st) { }
void g2(struct Student *pst) { printf("%6d, %8s, %4d\n", pst->sid, pst->name, pst->age); }
int main() { struct Student st; f(&st); g2(&st); }
|
四、关键对比
| 传值方式 |
能否修改外部变量 |
效率 |
值传递 f(int p) |
❌ 不能 |
较低(复制整个对象) |
地址传递 f(int *p) |
✅ 能 |
高(只传地址) |
| 访问方式 |
示例 |
| 变量名.成员 |
st.sid |
(*指针).成员 |
(*pst).sid |
指针->成员 |
pst->sid |
五、易错点
字符串赋值:不能直接用 = 给字符数组赋值,必须使用 strcpy()
1 2 3 4 5
| st.name = "lisa";
strcpy(st.name, "lisa");
|
指针访问结构体:(*pst).sid 的括号不可省略,因为 . 优先级高于 *
九、完整代码下载
源代码文件:Pointers-and-Structs-in-C.c