第21课 - 指针基础
口诀:加*符号变大门
- 变量回顾
既然程序中的变量只是一段储存空间的别名,那么是不是必须通过这个别名才能使用这段存储空间?我们看下面的例子:
#include<stdio.h>
int main()
{
int i = 5;
int* p = &i;
printf("%d,%08X ",i,p);
*p = 10;
printf("%d,%08X ",i,p);
return 0;
}
我们会看到,两次i的值分别是5和10。也就是说,即使变量是一段储存空间的别名,但是我们要改变它的内容(通过指针),也不一定非得通过这个别名来改变。也就是说*p = 10;等价于i = 10。
- 指针的本质
l 指针在本质上也是一个变量
l 指针需要占用一定的内存空间
l 指针用于保存内存地址的值
下面我们来思考:不同类型的指针占用的空间内存大小相同吗?
答:指针是用来保存地址的,所以指针的大小是一定的,和你运行的系统有关和类型无关。但是不同类型的指针,指向不同的内容。
- *号的意义
(1)在指针声明时,*号表示所声明的变量为指针。
(2)在指针使用时,*号表示取指针所指向的内存空间中的值。
*号类似医院吧钥匙,通过这把钥匙可以打开内存,读取内存中的值,例程:
#include <stdio.h>
int main()
{
int i;
int* pI;
char* pC;
float* pF;
pI = &i;
*((int*)0X18FF44) = 100;
//这行程序进行了强制的类型转换,18FF44相当于pI的地址,也相当于一扇大门(凡是指针都相当于大门),我们在前面加*,就等于打开了这扇大门。给它复制,我们就相当于给i赋值。
printf("%0X, %0X, %d ", pI, &i, i);
printf("%d, %d, %0X ", sizeof(int*), sizeof(pI), &pI);
printf("%d, %d, %0X ", sizeof(char*), sizeof(pC), &pC);
printf("%d, %d, %0X ", sizeof(float*), sizeof(pF), &pF);
return 0;
}
- 传值调用与传址调用
(1)函数调用的本质是将实参值复制到形参。
(2)传值调用中实参、形参为各自函数的局部变量,则形参在函数内数值变化不会影响外部实参的变化。
(3)传址调用中将复制的指针,故形参、实参的地址一样,形参的变化即实参的变化。
(4)当一个函数体内部需要改变实参的值,则需要使用指针参数。另外,指针适用于复杂数据类型作为参数的函数中。
例子:利用指针实现数据的交换。
(1)通过宏定义
#include<stdio.h>
#define SWAP(a,b){int t=a;a=b;b=t;}
int main()
{
int i = 2;
int j = 3;
printf("%d,%d ",i,j);
SWAP(i,j);
printf("%d,%d ",i,j);
return 0;
}
(2)通过函数
#include<stdio.h>
void SWAP(int *a,int *b)
{
int i = 0;
i = *a;
*a = *b;
*b = i;
}
int main()
{
int i = 2;
int j = 3;
printf("%d,%d ",i,j);
SWAP(&i,&j);
printf("%d,%d ",i,j);
return 0;
}