指针
程序员文章站
2024-01-01 17:12:10
...
指针可以理解成是一个变量,一个用来存放地址的变量。(存放在指针中的值都被当成地址处理)指针的出现就是为了存放地址,而地址就相当于一个门牌号,让内存更容易被访问。指针的大小在32位平台上为4个字节,在64位平台是8个字节。
指针类型
指针和变量一样有不同的类型,比如int,char,double,float等。
那定义了类型指针有什么意义呢?
1.有了类型的区分,就相当和法律一样有了规则,使得代码更加严谨。
2.确定了指针运算的规律 (可以参考我之前写过的一篇有关数组的运算博客)。
3.在指针+-整数中,表示指针向前或向后的移动,相应类型所占内存单位大小乘整数值就是指针移位的大小。
4.在指针的解引用中,指针的类型就决定了解引用的时候有多大的权限(能操控几个字节)。
比如:char* 的指针解引用就只能访问一个字节,int* 的指针解引用就能访问四个字节。
那定义了类型指针有什么意义呢?
1.有了类型的区分,就相当和法律一样有了规则,使得代码更加严谨。
2.确定了指针运算的规律 (可以参考我之前写过的一篇有关数组的运算博客)。
3.在指针+-整数中,表示指针向前或向后的移动,相应类型所占内存单位大小乘整数值就是指针移位的大小。
4.在指针的解引用中,指针的类型就决定了解引用的时候有多大的权限(能操控几个字节)。
比如:char* 的指针解引用就只能访问一个字节,int* 的指针解引用就能访问四个字节。
接下来将会介绍数组与指针之间的一些微妙关系。
首先,我们必须明确的知道,数组和指针之间没有任何的关系。
指针就是指针,在32位平台下永远占有4个byte,其意义就是某一个内存的地址。指针可以指向任何地方,但不是任何地方你都能通过这个指针访问到。
数组就是数组,其大小与元素的类型和个数有关。定义数组时必须指定其元素类型和个数。数组可以存任何类型的数据,但不能存函数。
下面就通过指针和数组的声明定义来详细介绍
首先,我们必须明确的知道,数组和指针之间没有任何的关系。
指针就是指针,在32位平台下永远占有4个byte,其意义就是某一个内存的地址。指针可以指向任何地方,但不是任何地方你都能通过这个指针访问到。
数组就是数组,其大小与元素的类型和个数有关。定义数组时必须指定其元素类型和个数。数组可以存任何类型的数据,但不能存函数。
下面就通过指针和数组的声明定义来详细介绍
声明是其实就是定义的变量
文件1中定义如下
char arr[] = "ABCDEF";//数组的定义
char* p = "ABCDEF"; //指针的定义
文件2中声明如下
extern char arr[];
extern char* p;
int main()
{
printf("%s\n",arr);
printf("%s\n",p);
}
输出的结果为: ABCDEF
ABCDEF
ABCDEF
上面的结果很容易得出,那么现在换一种方式,定义为数组,声明为指针:
文件1中定义如下
char arr[] = "ABCDEF";//数组的定义
文件2中声明如下
extern char *arr;
int main()
{
printf("%s\n",arr);
}
则输出结果会变成什么呢?
通过调试我们会发现出现异常
那么下来就详细解释一下异常的原因(不考虑大小端存储问题)
那么现在改成定义为指针,声明为数组呢?
文件1中定义如下
char arr* p = "abcdef";//指针的定义
文件2中声明如下
extern char p[];
int main()
{
printf("%s\n",p);
}
会发现结果输出了随机值
那么现在解释一下为什么会输出随机值(不考虑大小端问题)
通过上面的举例明确了解到数组与指针不能相互混淆。
接下来介绍一下指针数组与数组指针
指针数组:指针数组是数组,一个存放指针的数组,可以理解为"指向数组的指针"。
数组指针:数组指针是指针,一个指向数组的指针,可以理解为"存储指针数组的"。
下面的那个是指针数组,哪个是数组指针?
(1) int *p1[10]
(2) int (*p2)[10]
通过符号之间的优先级可以判断,"[]"的优先级要比"*"的优先级要高。因此当"[]"和p1结合时,构成了一个数组的定义,这是一个数组,数组名为p1,其包含了10个指向int类型数据的指针,即为指针数组。对于p2,由于"()"的优先级高于"[]",则"*"和有p2先结合构成了一个指针的定义,则就可以清楚p2是一个指针,指向了一个包含10个int类型数据的数组,即为数组指针。
数组指针:数组指针是指针,一个指向数组的指针,可以理解为"存储指针数组的"。
下面的那个是指针数组,哪个是数组指针?
(1) int *p1[10]
(2) int (*p2)[10]
通过符号之间的优先级可以判断,"[]"的优先级要比"*"的优先级要高。因此当"[]"和p1结合时,构成了一个数组的定义,这是一个数组,数组名为p1,其包含了10个指向int类型数据的指针,即为指针数组。对于p2,由于"()"的优先级高于"[]",则"*"和有p2先结合构成了一个指针的定义,则就可以清楚p2是一个指针,指向了一个包含10个int类型数据的数组,即为数组指针。
函数指针
顾名思义,函数指针就是函数的指针,他是一个指针,指向一个函数。
例:char *(*fun)(char *p1, char *p2);
在这里我们其实可以这样理解:char *(*)(char *p1, char *p2) fun;
这里的fun是一个指针变量,它指向一个函数,并且这个函数有两个指针类型的参数,函数的返回名也是一个指针。
当理解了数组指针,指针数组和函数指针时,那函数指针数组和函数指针数组的指针又该怎么理解:
函数指针数组的定义:char *(*pf[3])(char *p)
相当于的函数的地址存储的一个数组当中,这个数组就叫做函数指针数组。
函数指针数组的指针定义:cahr *(*(*pf)[3])(char *p)
指向函数指针数组的指针是一个指针,指针指向一个数组,数组的元素都是函数指针
二级指针
例:char **p
定义一个二级指针变量p。p为一个指针变量,在32为平台下为4个byte,p就相当于存放一级指p2的地址而p2
又是存放c的地址。
定义一个二级指针变量p。p为一个指针变量,在32为平台下为4个byte,p就相当于存放一级指p2的地址而p2
又是存放c的地址。