系列连载
参考
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 个地址
地址:
指针就是地址,地址就是指针
指针变量就是存放内存单元编号的变量,或者说指针变量就是存放地址的变量
指针和指针变量是两个不同概念,但是要注意,通常我们叙述时会把指针变量简称为指针,实际含义并不一样
指针的本质是一个操作受限的非负整数(不能加减除,只能减)
#include
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 就错了
以交换 a 和 b 的值为例
#include
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
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
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