浅谈指针

来源:互联网 发布:java转json忽略字段 编辑:程序博客网 时间:2024/05/21 08:48

指针是什么?
在计算机科学中,指针(Pointer)是编程语言中的一个对象,利用地址,它的值直接指向(points to)存在电脑存储器中另一个地方的值。由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。意思是通过它能找到以它为地址的内存单元。
我们可以用代码理解:

#include<stdio.h>int main(){   int a = 10;//在内存中开辟一块空间   int *p = &a;//取出变量a的地址,并将变量a的地址存放在p变量中,   return 0; //p就是一个指针。}

总结:指针就是变量,用来存放地址的变量。(存放在指针中的值都会被当成地址处理)
为什么存在指针?
我们知道我们的计算机要将程序运行起来,其实是要将程序加载到内存的。
那如何分配使用呢?
现实生活中我们管理土地的方式是:
一个国家 -> n个省 -> 每个省又划分为m个市 -> 每个市又划分县 ….. 一直到某个街道,某个楼,某个房间。
这样做的好处是我们可以很好的将土地分区管理,然后通过一个地址就能找到对应的位置。方便了管理。
其实计算机的内存管理也是采用了这样的思路:
将计算机的内存分成很多个小的单元,每个单元都对应一个独一无二的地址,这样就一个地址标示一块空间。
那这里的问题就是:
1、一个小的单元到底是多大?(一个字节)
2、如何编址?
经过仔细的计算和权衡我们发现一个字节给一个相应的地址是比较合适的。
对于32位的机器,假设有32根地址线,那么假设每根地址线在寻址的时候产生一个电信号(0或1),那么32根地址线产生的地址就会是:

00000000 00000000 00000000 0000000000000000 00000000 00000000 00000001...11111111 11111111 11111111 11111111这里就有2^32个地址。每个地址表示一个字节,那我们就可以给4G的空间进行编制。

总结:
指针是存放地址才出现的,地址是为了标示一块地址空间的。
指针让地址有地方存放,指针让内存的访问更加方便。
指针的大小在32位平台是4个字节,在64位平台是8个字节。
指针类型
我们都知道,变量有不同的类型,整形,浮点型等。那么指针也应该有类型。
指针的类型是:type + *的方式。
char* 类型的指针是为了存放 char 类型变量的地址。
short* 类型的指针是为了存放 short 类型变量的地址。
int* 类型的指针是为了存放 int 类型变量的地址。

为什么这么做?
1、只要有类型的区分,就定出一定的规则,使得编码更加严谨。
2、确定了指针运算的规律。

指针的类型决定了指针向前或向后(指针+-1)走一步的距离有多大。
也就是说,对整型指针+-1实际上加(或减)的是该指针类型的大小。
指针的类型决定了,对指针解引用的时候有多大的权限(能操作几个字节)。
比如:char*的指针解引用就只能访问一个字节,而int*的指针的解引用就能访问四个字节。

接下来,我们在说说对指针的一些特殊用法:
1、指针数组
指针数组是指针还是数组?
是数组!是一个存放指针的数组。
例如: int *arr1[10], char *arr2[10];
这里的表示的就是指针数组了,因为“[]”的优先级要高于“*”的优先级,所以这里的arr先于[]结合,所以是数组。
2、那么: int (*p)[10],这表示的是什么呢?这里的p又是什么呢?
答案:这里表示的是一个数组指针,这里的p是指针,是指向一个数组的指针。因为这里加上了()保证“*”先与p结合,所以p是指针。
3、函数指针
首先看一段代码:

#include<stdio.h>#include<windows.h>void test(){    printf("hehe\n");}int main(){    printf("%p\n", test);    printf("%p\n", &test);    system("pause");    return 0;}

输出的结果:
这里写图片描述
输出的是两个地址,这两个地址是 test 函数的地址。
那我们的函数的地址要想保存起来,怎么保存?
首先,能存放地址的肯定要是指针,如下:

void (*pfun)();

说明pfun是指针,指针指向的是一个函数,指向的函数无参数,返回值类型为void。
4、函数指针数组
数组是一个存放相同类型数据的存储空间,那我们已经学习了指针数组,
比如:

int *arr[10];//数组的每个元素都是int*

那要把函数的地址存到一个数组中,那这个数组就叫函数指针数组,那函数指针的数组如何定义呢?

int (*parr[10]])();

parr 先和 [] 结合,说明parr是数组,数组的内容是什么呢?
是 int (*)() 类型的函数指针。
函数指针数组的用途:转移表
5、指向函数指针数组的指针
指向函数指针数组的指针是一个 指针
指针指向一个 数组 ,数组的元素都是 函数指针 ;
如何定义?

void test(const char* str){ printf("%s\n", str);}int main(){   //函数指针pfun   void (*pfun)(const char*) = test;   //函数指针的数组pfunArr   void (*pfunArr[5])(const char* str);   pfunArr[0] = test;   //指向函数指针数组pfunArr的指针ppfunArr   void (*(*ppfunArr)[10])(const char*) = &pfunArr;   return 0;}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 无杆气缸行程大怎么办 c4d中模型变成线怎么办 内径槽异性需要车一刀怎么办 轴承太紧影响转速怎么办 电动车前轮蝶刹抱死怎么办 摩托三轮车油刹抱死怎么办 手动档汽车离合抱死怎么办 别克gl8后轮吃胎怎么办 扭力梁后轮吃胎怎么办 非独立悬挂吃胎怎么办 货车半轴法兰盘裂纹怎么办 小天才平板裂屏了怎么办 新车撞了个坑怎么办 新车碰了个坑怎么办 汽车顶被砸了个坑怎么办 途观l前减震异响怎么办 锦明8代声音太大怎么办 手机网页无法加载插件怎么办 微信公众号被投诉怎么办 住了酒店的尾房怎么办 喜欢前任的闺蜜怎么办 闺蜜给介绍对象怎么办 喜欢对象的发小怎么办 山东省直医保卡丢失怎么办 高铁票如果错过了怎么办 动车错过了时间怎么办 长途动车错过了怎么办 动车如果错过了怎么办 没有取票错过了怎么办 动车出站没检票怎么办 火车晚点耽误了下班车怎么办 动车票中途丢了怎么办 购买二手房异地铁路公积金怎么办 沈阳公积金卡丢了怎么办 住宅专项维修资金用完了怎么办 广州出租车丢了东西怎么办 广州的士丢了东西怎么办 网上找兼职被骗了怎么办 海信空调开不了机怎么办 海信空调遥控器开不了怎么办 学生遭套路贷反被仲裁怎么办