1.指针
计算机中所有的数据都必须放在内存中,不同类型的数据占用的字节数不一样,例如 int 占用 4 个字节,char 占用 1 个字节。为了正确地访问这些数据,必须为每个字节都编上号码,就像门牌号、身份证号一样,每个字节的编号是唯一的,根据编号可以准确地找到某个字节。
下图是 4G 内存中每个字节的编号(以十六进制表示):

我们将内存中字节的编号称为地址(Address)或指针(Pointer)。地址从 0 开始依次增加,对于 32 位环境,程序能够使用的内存为 4GB,最小的地址为 0,最大的地址为 0XFFFFFFFF。
2.取值符 取址符
* 为取值符 一般定义为变量操作符用于存取地址,在方法中表示从地址中取值
& 为取址符 一般为取变量的地址
*p按照Stanley Lippman的著作《C++ Primer》中的描述,p是指针变量,*是解引用操作符,*p是一个表达式,含义是“对指针变量p进行解引用操作”,这与表达式&a的含义“取整形变量a的地址”是正好是相反的操作。
#include <stdio.h>
int main(void)
{
int a=100;
int b=200;
int *c=&a;
int *d=&b;
int **e =&c;
int **f =&d;
printf("数字a= %d,数字b= %d \n",a,b);
printf("数字&a地址=%p,数字&b=%p \n",&a,&b);
printf("数字c地址=%p,数字d=%p \n",c,d);
printf("数字e地址=%p,数字f=%p \n",e,f);
printf("数字**e地址=%d,数字**f=%d \n",**e,**f);
return 0;
}
输出的结果为:
数字a= 100,数字b= 200
数字&a地址=0061FF24,数字&b=0061FF20
数字c地址=0061FF24,数字d=0061FF20
数字e地址=0061FF1C,数字f=0061FF18
数字**e地址=100,数字**f=200
3.指针在数组中的使用:
// 定义数组
int arr[] = {1,2,3,4};
// 遍历数组, linux 就有问题
//for (int i = 0; i < 4;i++){
//printf("%d\n",arr[i]);
//}
// for循环在 c 和 C++ 中的正确写法
int i = 0;
for (; i < 4; i++){
printf("%d\n", arr[i]);
}
printf("arr = %p\n", arr);
printf("arr& = %p\n", &arr);
printf("arr[0]& = %p\n", &arr[0]);
printf("arr[0]& = %p\n", &arr[0]);
//以上可以看到 arr = &arr = &arr[0] 三个变量中地址都是同一个
// 如何获取数组的指针
int* arr_p = arr;// 数组指针指向的是数组的首地址
// 做一系列的操作
printf("%d\n",*arr_p);
// 对指针进行 ++
arr_p++;
printf("%d\n", *arr_p);
// 指针再往后逻动两位
arr_p += 2;
printf("%d\n", *arr_p);
输出为:
1
2
3
4
arr = 0061FF14
arr& = 0061FF14
arr[0]& = 0061FF14
arr[0]& = 0061FF14
// 看一种现象: arr 的值 = arr 去地址的值 ,arr 地址的值 = arr[0]的地址的值(首地址)
1
2
4
4.方法指针
在方法中也能使用指针,可以把方法当成一个变量来进行使用
// 监听数据压缩回调
void call_back(int current,int total){
printf("压缩的进度是:%d/%d",current,total);
}
// 这个方法 3 ,他是一个额外的文件了
void compress(char* file_name,void(*callback)(int,int)){
callback(12,24);
}
void main(){
void(*call)(int, int);// 声明了一个函数
call = call_back;// 给函数指针赋值
// call(1,2);// 通过函数指针间接的调用call_back
compress("1.png", call);
getchar();
}
输出为:
压缩的进度是:12/24

网友评论