从5个维度来看C语言指针(指针就是个纸老虎)菜鸟教程

本文中,我对指针总结的维度,用四个字来概括,就是:"两己三他"!是不是读起来一点都不顺口,一点都不押韵啊,什么个玩意儿。这"两己三他",展开来说,就是:己址、己值、他值、他址、他型。

我觉得可以从这5个维度再来聊聊指针。不过在聊之前,我写了个程序,把指针的"两己三他"维度都包含进来,然后再来一个一个解释每个维度的意思,你看看是不是这回事儿。

在大部分的使用指针的场景下,这5个维度应该足够帮你去理解了。不过在一些使用指针特殊的场景下,可能5维度法帮助不了你。

运行的结果如下:

程序中:

intpara=1;printf("变量para自己的地址是:0X%x\n",¶);printf("变量para自己的值是:0X%x\n",para);定义了变量para,它有自己的数据值,也有自己的存储地址,这些个都很好理解。从运行结果来看,变量para自己的数据值是16进制的"0X1",地址是16进制的"0X22feb4"。换句话说,在内存中,地址为"0X22feb4"开始的存储空间,有4个字节存储了一个数据值"0X1"。在我的机器上,一个int型变量占用4个字节,在你的机器上可能与我不一样。

关于int型变量para大家都好理解。下面,我来画一个示意图,来指明变量para在内存中存储的情况,如下:

下面开始说说"两己三他"的概念。

"两己三他",展开来说,就是:己址、己值、他值、他址、他型。

2.1.1"己址"的概念

"己址",就是"自己的地址"的简称。指针pInt作为一个变量,与int变量para一样,也需要存储在内存中的一段存储空间,这段存储空间也会有一个开始地址,也就是说,指针变量pInt也会有自己的地址。上面说了,变量para的地址是"0X22feb4",那么,指针变量pInt的地址是啥呢?

2.1.2"己址"的获取

我们都学过,"&"是一个取地址的运算符,在程序中:

printf("指针变量pInt自己的地址是:0X%x\n",&pInt);就是通过"&"来获取指针变量pInt的地址。从运行结果来看,指针变量pInt的地址是"0X22feb8"。在我的机器上,指针变量pInt也是占用4个字节,因此,指针变量pInt存储在开始地址是"0X22feb8"开始的4个字节空间。

2.1.3"己址"的代码写法

在代码中,表示指针变量pInt的"己址"的代码写法,常见的是:

&pInt;现在,我们来完善那个示意图,图中加入指针变量pInt的"己址",指出指针变量pInt在内存中是怎么个存储形式。

"己址",就是这个意思。你看,没什么特别难的吧!

2.2.1"己值"的概念

"己值",就是"自己的数据值"的简称。指针pInt作为一个变量,跟变量para一样,也有着自己的数据值。

2.2.2"己值"的获取

上面提到,变量para自己的数据值是"1",那么指针变量pInt自己的数据值是多少。在程序中:

pInt=¶printf("指针变量pInt自己的值是:0X%x\n",pInt);我通过"&"运算符,将变量para的地址值赋给了指针变量pInt,通过printf来输出指针变量pInt的数据值。从运行结果中来看,指针变量pInt自己的数据值是"0X22feb4"。我们再看,变量para的地址也是"0X22feb4",所以,

pInt=¶这个语句的本质,就是将变量para的地址,给了指针变量pInt的己值,这样就将指针变量pInt与变量para绑定在一起了。

在"己址"中提到了,指针pInt的数据值存储在地址为"0X22feb8"开始的4个字节的内存上,那么也就是说,地址为"0X22feb8"开始的内存,后面的4个字节都用来存储着一个数据值"0X22feb4"。

2.2.3"己值"的代码写法

在代码中,表示指针变量pInt的"己值"的代码写法,常见的有

pInt;也有的代码写法是:

pInt+N;pInt-N;这种写法的意思是用pInt的"己值"加上一个数字N或者减去一个数字N,这个等讲到"他型"这个属性时会提到。也有的写法是:

pIntA-pIntB;这种写法表示的是两个指针变量用"己值"做减法。

2.2.4示意图

现在,继续来完善上面的示意图,加入指针变量pInt的己值。

所以,一般而言,"己值"对于指针变量pInt来讲,是自己的数据值;对其它的int类型的变量来讲,就是它们的地址。

2.3.1"他址"的概念

"他址"的概念就是"他人的地址"的意思。其实在上面提到己值时,就已经不那么明显地提到了"他址"的概念。

2.3.2"他址"的获取

整型变量para存储在内存地址为"0X22feb4"开始的4个字节。在程序中,我通过

pInt=¶将变量para的地址给了指针变量pInt,这样就将指针变量pInt与变量para绑定在一起了。更为本质的说,是把"他人的地址"赋值给了指针变量pInt的"己值",这里,"他人的地址"的"他",指的就是变量para,"他人地址的址"的"址",指的就是变量para的地址。注意,你看,"他址"和"己值"在数据值上是一样的,所以,你领悟出了什么东西来了没?

很多教材所谓的"指针是一个地址变量,存储的是其它变量的地址",说白了,就是在说"他址"这个维度的数据值等于"己值"这个维度的数据值,只是教材没说的那么明白。

2.3.3示意图

再来完善那个示意图,这次加入"他址"的概念。

2.4.1"他值"的概念

"他值",就是"他人的数据值"的意思。

2.4.2"他值"的获取

在程序中,我通过

pInt=¶将变量para的地址给了指针变量pInt的"己值",这样就将指针变量pInt与变量para绑定在一起了。这个时候,"他人的数据值"的"他",指的就是变量para,"他人的数据值"的"数据值",指的就是变量para的数据值"1"。在程序中,我通过

printf("指针变量pInt的他值是:0X%x\n",*pInt);也就是指针变量pInt前面加上"*",来输出指针变量的"他值",从运行结果来看,是"0X1"。注意,你看,指针变量pInt的"他值",与变量para的数据值是一样的,你又领悟到了什么?想不出来吗?继续看!

2.4.3"他值"的代码写法

你经常在代码中看到的那些个代码写法,比如什么*pInt写法,是在表达什么意思啊,其实就是在计算指针变量pInt的"他值"啊!

这些个写法呢:*(pInt+1)、*pInt+1、pInt[1]?

*(pInt+1):如果把pInt+1看成是另外一个指针,比如

int*pTemp=pInt+1;那么*(pInt+1)计算的本质上就是指针变量pTemp的"他值";

*pInt+1:这个就是用pInt的"他值"加1;

pInt[1]:这个呢?其实就是*(pInt+1)。

2.4.4示意图

继续完善上面的示意图,这次加入"他值"的概念:

2.5.1"他型"的概念

int*pInt=NULL;指针变量pInt前面的"int"并不是说指针变量pInt的"己值"是一个int类型的数据值;而是说,指针变量pInt的"他值"是一个"int"类型的数据值,此处指针变量pInt的"他值"是变量para的数据值"0X1",因此,指针变量pInt前面的"int"指的就是数据值"0X1"是一个"int"型。

在程序中,如下代码片段:

intarr_int[2]={1,2};pInt=arr_int;printf("arr_int第一个元素arr_int[0]的地址是:0X%x\n",pInt);printf("arr_int第二个元素arr_int[1]的地址是:0X%x\n",pInt+1);我把一个整型数组arr_int的地址赋给了指针变量pInt,那么pInt的"己址"没有变化,还是0X22feb8,但是"己值"却变了。

刚才指针变量pInt的"己值"还是"0X22feb4",也就是变量para的地址,现在变成了"0X22feac",这个可是数组arr_int第一个元素的地址。也就是说,指针变量pInt的"己址"不会改变,但是"己值"是可以被改变的。

现在我们来看看"pInt"与"pInt+1"的区别,这是在用pInt的"己值"在做运算。从运行结果来看,pInt的"己值"此时是"0X22feac",而pInt+1的"己值"是"0X22feb0",你发现了吗,两者正好相差4个字节,而一个"int"类型的数据也正好占用了4个字节。

你可能会认为,既然pInt+1是用"己值"加1,那么应该是"0X22feac+1"="0X22fead"才对啊,为什么不是这样呢?这就是指针变量pInt的"他型"搞的鬼。

"他型"的意思,用大白话来说,就是:"我说pInt大兄弟啊,你的他值是个int型的数据值,你今后要是用你的己值+1,+2,或者-1,-2,可千万别傻乎乎的就真的加1个字节,加2个字节,或者就真的减1个字节、减2个字节。人家int类型占4个字节,你就得按照4个字节为一个单位,去加1*4个字节、2*4个字节,或者减去1*4个字节、2*4个字节,知道不?哦,顺便说下,pInt+N的N,可以为正数也可以为负数"。

当然啦,如果你的机器上"int"型数据占8个字节,那么pInt+1就是在"己值"上加8个字节,pInt+2就是在"己值"上加8*2=16个字节,就这么个意思。

我在程序中又举了个例子来说明这个"他型"。程序如下:

是时候来总结下了。

type*pType=NULL;pType有5个维度,分别是:

pType=(己址,己值,他址,他值,他型);

指针变量pType作为一个变量,也有自己的地址,常见的代码写法是"&pType"。

己址在一般的程序中不会被频繁地用到,如果要用的话,就涉及到"指针的指针",这又是另外一个话题了,本文不讨论;

指针变量pType作为一个变量,也有自己的数据值,代码的写法是"pType"。

也可以在己值上做加减法运算,常见的代码写法有"pType+N"、"pType-N"、"pType2-pType1"等。

指针变量pType的己值,意义除了表示自己的数据值外,还表示了与pType绑定在一起的"type"类型的变量的地址。一般而言,指针变量pType的"己值"与"他址"在数据值上是一样的。

将一个type类型的变量与pType绑定在一起的常见方式是:pType=&变量;

一旦type类型的变量与pType绑定在一起,指针变量pType可以通过一些代码写法,来获取type类型变量的值,也就是"他值"。常见的代码写法有:"*pType"、"pType->"等。

而这些代码的写法:"*(pType+N)"、"*(pType-N)"、"pType[N]"也是获取的"他值",不过需要特别说明一下:

pType+N你可以看成是:

type*pTemp=pType+N;"*(pType+N)"其实计算的就是指针变量pTemp的"他值"。

"*(pType-N)"你就好理解了吧;

"pType[N]"其实就是"*(pType+N)",你就死记硬背吧。

"他型"在代码中的作用,主要是计算"pType+N"、"pType-N"时,pType要加上或者减去(N*sizeof(type))个字节。

指针总是让人晕晕的,很可能就是让你晕在这5个维度里的一个或者几个上。把这5个维度好好理解透,指针啊,只是个纸老虎。

讲完了5个维度,不来点上手习题怎么行。下面列举几个习题,都是跟指针有关的,都是让初学者晕的歇菜的。我用这5个维度来解读这些题,你看看是不是要轻松一点!

4.1.1程序

第一个例题是很常见的程序,就是求一个数组元素的和,程序如下:

程序很简单,先是输出数组的所有元素,然后计算出数组所有元素的和。运行结果如下:

4.1.2"两己三他"的解读

4.1.2.1输出数组元素

在输出数组元素时,代码如下:

pArr=arr;printf("%d",pArr[index]);这句代码等同于

pArr=arr;printf("%d",*(pArr+index));这里面使用了"己值"、"他型"做了加法运算,使用了"他值"获取数组元素。

"己值":代码先是将数组名arr的数据值赋值给了pArr的"己值"。而数组名arr的数据值是啥啊,是arr[0]元素的地址,对吧!那么pArr的己值,也是arr[0]的地址,对吧!这样一来,pArr就和arr[0]绑定起来了。

至于(pArr+index)的意思呢,你就看成有一个间接的、临时的指针变量pTemp:

int*pTemp=pArr+index;也就是说,pArr+index其实也是一个指针pTemp,只不过这个pTemp的己值是pArr的己值加上index*sizeof(int)个字节数。

"他型":pArr的他型是"int"型,pArr+index,是在pArr己值的基础上,加多少个字节呢?pArr的他型是int型,那么pArr+index,是不是意味着pArr的己值加上index*sizeof(int)个字节啊!

pArr:可以写成pArr+0,就是加上0*4=0个字节,此时pTemp的己值是arr[0]的地址;

pArr+1:就是加上1*4=4个字节,此时pTemp的己值是arr[1]的地址;

pArr+2:就是加上2*4=8个字节,此时pTemp的己值是arr[2]的地址;

这样,pArr+index就遍历到了数组所有元素的地址了。

你会发现,pTemp的己值,一直在发生变化;pArr的己值和己址,一直未变。

"他值":既然pArr+index能够遍历到数组所有元素的地址,再使用*(pArr+index),也就是*pTemp,是不是就能获取到pTemp的他值了,这样也就变量到数组所有元素的值了!

4.1.2.2数组元素求和

求数组元素的和时,使用的代码如下:

sum=sum+*(pArr+index);根据刚才我对输出数组元素的分析,这句代码中pArr是怎么玩的,大家也清楚了吧!

pArr+index依然是在用pArr的己值做加法运算,获取到一个临时指针pTemp的己值,这个pTemp的己值是每个数组元素的地址;

再用*(pArr+inedx),也就是*pTemp,获取临时指针pTemp的他值,也就是每个元素的值。

最后将pTemp的每一个他值,叠加起来,算出数组元素的和。

4.1.2.3总结

大家试着用"两己三他"的维度去理解pArr、pArr+index、*(pArr+index)、pArr[index]、*pArr+index等常见的代码写法!

4.2.1程序

指针数组,我举了一个例子如下:

运行结果如下:

4.2.2"两己三他"的解读

4.2.2.1输出所有的字符串

先看指针数组的定义:

char*arr[3]={"abc","def","ghi"};你看到的这个数组的每个元素好像是一个字符串,其实本质上是这样的:

char*pChar1="abc",*pChar2="def",*pChar3="ghi";char*arr[3]={pChar1,pChar2,pChar3};数组arr的每个元素其实是一个"他型"是"char"的指针。

arr[0]就是pChar1这个指针,那么pChar1的己值或者他址是啥,当然是字符串"abc"的字符'a'的地址,那么:

printf("%s",arr[0]);本质上是:

printf("%s",pChar1);使用pChar1的己值或者他址,从字符'a'的地址开始,一个一个地输出后面的'b'和'c'。

对于pChar2和pChar3也是一样地理解。

4.2.2.2输出第一个字符串"abc"的每个字符

代码如下:

char*pArr=arr[0];printf("%c",*(pArr+index));将arr[0],也就是pChar1的己值给了pArr的己值,那么pArr的己值和他址都是字符'a'的地址。

pArr+index是在pArr的己值上,加上index*sizeof(char)个字节,给了一个临时指针变量pTemp:

char*pTemp=pArr+index;这个指针pTemp的己值或者他址,会依次为字符'a','b','c'的地址,也就是pTemp的他值也会依次为字符'a','b','c',这样指针pTemp就会依次遍历到字符串"abc"的每一个字符了。

链表是使用指针最为频繁的,什么插入节点、删除节点等,都会遇到如下的代码写法:

THE END
1.ABC是什么意思ABC怎么读中文意思用法ABC 基本解释 n.字母表(尤指儿童学习的全部字母);(某学科的)基础知识,入门;abbr.美国广播公司(美国一家全国性的大型电视广播公司);出生在美国的华人(American - born Chinese);代理商-商家-消费者的商业模式(Agent, Business, Consumer) ABC 词性变化 https://danci.gjcha.com/ABC.html
2.啥玩意是404报错?问答理想情况下,网站不应该出现404错误。但是,如果网站拥有大量的页面这是无法避免的。当一个网页被绕过时https://developer.aliyun.com/ask/301907
3.不讨论别的,我单纯想知道ghg又是什么玩意[鲨鱼娘瞅瞅]不讨论别的,我单纯想知道ghg又是什么玩意字母真是被你们玩明白了abcdefj的 点赞4评论7评论7 现实恶魔困扰着我 girls hurt girls 第1 楼04-16回复0点赞1 亦坑亦怂 不知道?♂? 第2 楼04-16回复0点赞0 管中鲔鱼的生命周期 这是中文吗我想问问 第3 楼04-16回复0点赞0 木星网友卡提斯 手游https://yubam.douyu.com/post/632233641713233016
4.abc是哪个领域的品牌呀?由于不知道“abc”具体是什么品牌,很难确切说出它属于哪个领域。不过有一些方法可以大致推断。如果“abc”是一个比较知名的大众品牌,我们可以从常见的消费领域去考虑,例如它可能是服装领域的品牌,像耐克、阿迪达斯等品牌就专注于运动服装及相关装备;也可能是食品领域的品牌,像可口可乐、娃哈哈等主要生产https://zhidao.baidu.com/question/1809596243782996187.html
5.牛欢喜是啥玩意理想股票技术论坛相关标签:牛欢喜是什么玩意图片 牛欢喜游戏有挂吗 牛欢喜价格怎么样 牛欢喜是啥玩意 牛欢喜是干嘛的 阅读657 回复1 赞0 《揭秘牛欢喜源码背后的股票分析策略》 [股票知识指标公式概念题材] 小柯ABC 2023-7-24 相关标签:牛欢喜是什么玩意图片 牛欢喜出自哪部电影 牛欢喜是什么玩意儿 牛欢喜是干嘛的 牛欢喜https://www.55188.com/tag-2296438.html
6.《水星的魔女》最后一集,我是真不知道我看了个啥玩意……《水星的魔女》最后一集,我是真不知道我看了个啥玩意…… 《水星的魔女》最后一集,我是真不知道我看了个啥玩意,这是高达?https://k.sina.cn/article_1648894531_6248224304001hutm.html
7.www.camdex.cn/aplpage16768.html一,欧美足交视频,女生叫男生?自己坤坤动漫。电影 二,激情性爱黄色视频免费动态图,gogo西西rtys 三,14ⅩⅩXB,揉捏浑圆花蕾 四,男生的坤巴扎进女生的坤巴里免下载观看,男女国产免费观看 五,欧美牲交a欧美牲交aⅴ片,好湿国产精品 六,在线免费看av可搜索,777色色视频 http://www.camdex.cn/aplpage16768.html
8.阅读,回答问题。一把斧头的记忆赵明山改变我命运的人叫储国恩,是冀中抗他施展本事的场所都在贫民区——那儿他常搞点偷鸡摸狗的玩意,有时他甚至沿路要饭——行乞可是泰葛的拿手好戏。胆小如鼠的小商人们看见五大三粗的泰葛,便会心里打鼓——于是一边注视着他的大“铁掌”,一边乖乖地从口袋里掏出几个子儿来。泰葛在人行道上走了一程,到拐角处又转回来,他看到两个神秘的https://www.jyeoo.com/shiti/10e11b7c-1571-4915-8582-5f5a5a227f25
9.www.jxmzxx.com{$woaini}>www.jxmzxx.com{$woaini}连日来,受持续暴雨影响,海南省琼海市石壁镇石壁村、下朗村,博鳌镇莫村共约1400余名群众受困。灾情就是命令,琼海市人武部组织36名民兵应急队员,携冲锋舟3艘、运输车1台,协调驻琼海部队官兵80余人携冲锋舟5艘、皮划艇6艘、运输车10台,紧急转移受困群众。 http://www.jxmzxx.com/appnews/660272.html
10.www.tuanshan365.com/lixinniannianzixunwww.tuanshan365.com/lixinniannianzixun-3.shtml 156.45MB 下载APK 下载亚洲日日日安装你想要的应用 更方便 更快捷 发现更多 256 详细信息 软件大小: 最新版本: 一,777米奇色狠狠888俺也去网,被狂躁的护士爽得嗷嗷叫 二,在线观看国产外围视频,a色片播放https://www.tuanshan365.com/lixinniannianzixun-3.shtml
11.智能算法变邻域搜索算法(VariableNeighborhoodSearch,VNS85//所谓城市序列,就是城市先后访问的顺序,比如可以先访问ABC,也可以先访问BAC等等 86//访问顺序不同,那么总路线长度也是不同的 87//p_perm 城市序列参数 88intcost_total(int* cities_permutation, CITIES * cities) 89{ 90inttotal_distance =0; https://www.west.cn/info/html/chengxusheji/C-C--/20180703/4262043.html
12.Linux常用命令时刻更新51CTO博客--help命令用于显示shell内部的帮助信息。help命令只能显示shell内部的命令帮助信息。而对于外部命令的帮助信息只能使用man或者info命令查看。 grep 1. root@healerjean:~# grep --help Usage:grep[OPTION] PATTERN [FILE] SearchforPATTERNineach FILE or standard input. https://blog.51cto.com/u_15773996/5639709
13.听说长期用ABC会变黑木耳,是真的么?啥时候大众才能懂点科学?!唉…… 赞 回应 [已注销] 2011-10-10 00:36:39 [内容不可见] 赞 回应 .天天天晴. (静水深流.) 2011-10-10 00:41:43 我木有那个生活也木有用ABC怎么很黑啊,求解啊!!! 赞 回应 hill 2011-10-10 00:47:26 充血你妹啊,完全是色素原因好么有些皮肤黑的姑娘天生https://www.douban.com/group/topic/22798181/?cid=283045018
14.数学思维是什么?如何培养?对了,下面这个是你学高等数学的时候看到的导数定义。这是个啥玩意?不用管这是个啥玩意。还有个极限https://www.zhihu.com/question/25709807/answer/2982132618?utm_id=0
15.HIFIDIY论坛夏普GF777收录机后部,录音开关ABC三档干什么用的。没有中文说明书。有说明书的点一步。http://bbs.hifidiy.net/thread-1465370-1-1.html
16.带着朋友和机器人上月亮散步五问:天使投资人到底是什么玩意,其使命究竟该是什么? 天使投资这两年纷嚣尘上,对中国互联网的促进发展有目共睹,一段时间内其风头似乎盖过了所有的VC。作为一个新生事物,中国的天使投资还有很长的路要走,这个行业还充斥着大量的跟风、浮躁与不专业。天使投资作为整个投资产业的最前端,它必定是所有投资阶段中失败率https://www.huxiu.com/article/2857.html
17.www.xinhsen.com/aplpage31099.htmlwww.xinhsen.com/aplpage31099.html 部分聊天记录来源网络 号主表示:他和管家关系并不是所谓的朋友,他们之所以认识,是因为去年帮号主开了3个月号,号里有一组林中鸟,要什么装备我给他买什么装备,没收租金,没收押金,三界不够要求号主给补,号主感觉亏钱就闹崩了。http://www.xinhsen.com/aplpage31099.html
18.一看就懂:正则表达式不用背java正则校验正则:[abc] 正则:[^abc] 正则:[a-z] 正则:[^a-z] 正则:\num 正则:? 正则:+ 正则:{n} 正则:{n,m} 正则:* 命名规范 结构组成 用途场景 Java中的正则校验 正则元字符 Part1案例引入 在讲正则表达式前,我们不妨先从一个场景来逐渐引入。 https://blog.csdn.net/caryxp/article/details/134525196
19.情绪派杰哥(柚子小杰杰)柚子园交易干货在波浪理论里,退潮段可分为ABC浪,也引申为周期里的退潮初期–退潮中期(反弹)–退潮后期(崩溃)。 (1)退潮初期 退潮初期空间坍缩,这个阶段特点是冰火两重天,亏钱的票都是大亏,但赚钱的票也还能继续大赚,尤其是缩量连板,表象上很容易蒙蔽掉亏钱效应,能接力的易大面,大肉的几乎没好的接力机会,直观感受是涨的凶https://www.logic58.com/14101.html