C指针详细讲解(帮助理解)

指针,是一种数据类型,是用来存储地址的数据类型。

我们可以通过定义指针变量,然后给这个指针变量中存储地址,然后再通过指针来访问这个地址所对应的内容。

上面的是指针的基本感念,几乎所有的C语言学习者都会在书籍中看到这样的概念,但是并不会详细讲解指针应该如何进行理解。我个人对指针变量的理解是:指针,通过名字可以理解为一根针,这根针指向一个内存地址,将这个内存地址存储在一个指针变量中,在需要用的时候,通过对这块内存地址中内容的访问,来拿到所需要的东西。

#include<stdio.h>

int main()
{
    int *p = "hehe";
	
    int *pp = NULL;
    pp = "hello word";
	
    return 0;
}

记住,在定义指针类型的时候,一定要对指针内容进行初始化。如果没有对指针内容进行初始化,那么这个指针变量中所存储的就是一个随机值,这个指针所指向一块垃圾地址,这个指针就是一个野指针。如果对这个指针所指向的内容进行访问,就会发生错误。而且如果不小心对这块内存地址的内容进行修改,就会发生难以预料的结果。因为在计算机运行的过程中,有很多东西在内存中运行,如果突然对这块内存地址的内容进行修改,就可能会打断其中的一个程序的正常运行,会导致非常严重的错误。如果定义的时候指针没有指向一个明确的地址,那么就在定义的时候,让指针指向空地址,即NULL,NULL的值就是0,pp就是一个空指针。由于计算机会对内存地址为0的位置进行硬件保护,所以不能进行内容的访问,也不能进行修改。然后在需要的时候,对这个指针变量进行赋值,让它指向一块合法的内存地址。

NULL是一个宏定义,是0。

好了,这就是基本的概念了,那么我们来看看指针数组、数组指针、指针函数、函数指针、等等很多很多让人头皮发麻的东西。其实那些复杂的类型,只不过是一个个简单的类型拼接起来的,当你看到的时候,一定要冷静分析,越是冷静,看到的东西就越多。    

首先,我们来看看运算符的优先级,在指针这里最重要的就是运算符的优先级,只有明白了优先级,才会理解为什么会出现各种各样的类型。

* 和 [ ] 和 ( ) ,这三个运算符,因为优先级的不同,导致了指针的多种变化。( ) 这个运算符的优先级是最高的,不论何时,一定是先对他修饰的进行处理。[ ]的优先级是高于*的优先级的,所有但他们两个同时出现的时候,计算机会优先进行 [ ] 处理(我不知道具体的用词应该是什么),比如   int* p[2]  这个的意思是定义一个有两个元素的数组,每个元素是一个指针。因为计算机优先对[]进行了处理,所以计算机首先认为这是一个数组,然后再对*进行处理,这里就有一个先入为主的概念了,因为计算机已经确定了p是一个数组,那么既然是一个数组了,那么数组就是p的主,而 * 及指针则是次,那么计算机就会认为这个数组的元素是指针类型。这里还有一个重要的概念 :在指针和数组混合起来应用的时候,会有一个逐级向内的特性。意思就是一个数组,他是主体,而他的次就是他存储的元素,而他的元素又是他的元素的元素的次,依次相对为主次。这么说可以理解吗?如果不能,那我们就来看例子 :a->b->c->d  ,看,a是b的老大,b时c的老大,c是d的老大,[ ]和* 运算符在运算的时候,会遵循这个原则,逐级向内访问, 访问的等级也会越来越低。

这样就差不多可以理解了吧!其实这个只要你看的例题多了,就自然而然就会了。话不多说,咋们直接上例子:

int *p1[10];
int (*p2)[10];

这两个例子,一个是指针数组,一个是数组指针。命名规则是将等级高的放在后面。p1是一个数组,数组元素是指针类型。p2是一个指针,这个指针所指向的类型是一个有是十个元素的数组类型。能看懂这个例子吧?如果如果看不懂,记得一定要注意优先级,因为访问的优先级是突破的关键。

接下来咋们来看看函数指针和指针函数:

函数指针:函数指针是一个指针,这个指针指向一个函数,这个函数含有多个参数。

指针函数:指针函数是一个函数,函数的返回值是一个指针。

那么我们接下来加入函数指针,和指针函数试试看你还能不能理解:

其实这不过是一个反复的运算符访问。下面的第一个例子是:这是一个指针,指针指向一个参数是char* 类型的指针,返回值是int*类型指针的函数。  第二个例子是:这是一个数组,这个数组的每个元素是一个指针,指针指向一个参数是char* 类型的指针,返回值是char*类型指针的函数。看的时候,一定是从最中心的位置开始,然后逐一分析,就可以得出最终的答案。这里的中心就是我们上面讲到的数组指针和指针数组,从这里开始看,然后在最后将函数指针和指针函数加进去就可以了。

int *(*pf)(char * p);
char*(*pf[3])(char *p);//这两个例子出自《C语言深度剖析》

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值