系列连载
- 【python / C / C++】
参考
- 《C语言程序设计(第四版)谭浩强》
- 【C语言】C语言视频教程
- 《郝斌 C 语言自学教程》
文章目录
- 一、指针的重要性
- 二、指针的定义
- 三、指针的分类
- 基本类型指针
- 指针和一维数组
- 指针和函数
- 指针和结构体
- 多级指针
int * p;
// p 是变量的名字,int * 表示 p 变量存放的是 int 类型变量的地址
// int * p 不表示定义了一个名字叫做 * p 的变量
// p 变量的数据类型是 int * 类型,所谓 int * 类型就是存放 int 变量地址的类型
int i = 3;
p = &i;
// p 保存了 i 的地址,因此 p 指向 i
// p 不是 i,i 也不是 p, 更准确的说:修改 p 的值不影响 i 的值,修改 i 的值不影响 p 的值
// 如果一个指针变量指向了某个普通变量,则 *指针变量 就完全等价于 普通变量,
//例子,如果 p 是个指针变量,并且 p 存放了普通变量 i 的地址,则 p 指向了普通变量; *p 就完全等价于 i,或者说在所有出现 *p 的地方都可以替换成 i
//*p(取值符) 就是以 p 的内容为地址的变量
p = &i
*p = i
一、指针的重要性
指针:
- 表示一些复杂的数据结构
- 快速的传递数据
- 使函数返回一个以上的值
- 能直接访问硬件
- 能够方便处理字符串
- 是理解面向对象语言中的基础
总结:
指针是 C 语言的灵魂
二、指针的定义
内存条一块地址,1 Byte = 8 bit
32 位一次读 4 个地址
地址:
- 内存单元的编号
- 从零开始的非负整数
- 范围:4G(0~4G-1)
指针就是地址,地址就是指针
指针变量就是存放内存单元编号的变量,或者说指针变量就是存放地址的变量
指针和指针变量是两个不同概念,但是要注意,通常我们叙述时会把指针变量简称为指针,实际含义并不一样
指针的本质是一个操作受限的非负整数(不能加减除,只能减)
#include<stdio.h>
int main(){
int* p;
int i = 5;
p = &i;
//*p = i;
printf("%d\n", *p);
return 0;
}
output
5
上述代码如果用 *p = i
替换 p = &i
, 则会出现垃圾地址,野指针
只分配没有释放( free) 就存在内存泄漏(越用越少)
多个指针指向同一块动态内存,free 一个就行,多次 free 就错了
三、指针的分类
基本类型指针
以交换 a 和 b 的值为例
#include<stdio.h>
void change1(int a, int b){
int t;
t = a;
a = b;
b = t;
return;
}
int main(){
int a = 3;
int b = 5;
change1(a, b);
printf("a = %d, b = %d\n", a, b);
return 0;
}
output
a = 3, b = 5
由于 c 语言的函数只能有一个返回值,所有 change1
中不能写成 return a,b
可以看到 change1
函数并不能互换 a 和 b 的值
下面试试利用指针
#include<stdio.h>
void change2(int* p, int* q){
int* t;
t = p;
p = q;
q = t;
return;
}
int main(){
int a = 3;
int b = 5;
change2(&a, &b);
printf("a = %d, b = %d\n", a, b);
return 0;
}
output
a = 3, b = 5
发现还是没能交换,因为只是改变了两个指针变量存放的地址,并没有改变 a 和 b 的值
#include<stdio.h>
void change3(int*, int*);
int main(){
int a = 3;
int b = 5;
change3(&a, &b);
printf("a = %d, b = %d\n", a, b);
return 0;
}
void change3(int* p, int*q){
int t;
t = *p;
*p = *q;
*q = t;
return;
}
output
a = 5, b = 3