回 帖 发 新 帖 刷新版面

主题:关于指针和数组的若干问题

int *p;
int **pi;

p是一个指向整型变量的指针,那么pi是什么呢?pi的值可以是一个指向整型变量指针的address。这个解释是在书上抄下来的,方便我发问。

对于p我可以理解,一个指针变量。pi就不太明白了,解释是“pi的值可以是一个指向整型变量指针的address”,按照书中给的解释,我是不是可以这么理解?用几个问题,从几个方面,我想搞明白。以下便是:

1):先从p开始说,printf("%p%p", p, &p);假设p已被赋值,不加&给出的p中存储的值吗?那加了&是不是就是p本身的存储地址?

2):若问1中我的猜测正确,说实在的,其实我是想求证自己的想法到底对不对,免得把错的想法当成对的,不想又走弯跑。

pi = &p;这个表达式是否成立?pi的值是p的存储地址,而p的值又是赋给p的那个变量的地址,通过操作pi是不是可以操作那个赋给p的变量,对其中所存储的值进行使用或修改?pi是不是可以说是二维指针或者二级指针……因为我感觉是不是可以像理解二维数组那样理解这个pi。
我理解二维以上的数组就是纯粹的认为,在一个数组的基础上又有一个或者或者多个数组,把数据组合在一起罢了。我这样理解pi,对吗?

3):如果问2的想法是对的,假设pi是这样声明的int *** pi,也是同样的道理咯?

关于pi的问题暂时结束,以下的问题是关于“指针”的,为了方便,接着问3的序号,但问题内容不相关,以下便是:

4):指针,是不是“指针变量”的简称?我想外国人在确定“指针”这个名字的时候,是不是考虑到“指针”工作方式与钟表的针工作方式相像才取名为“指针”,汗,我为什么这么想,是一开始接触C的时候,我问一个朋友数组是怎么回事,他很明白的告诉我,就是一堆数的组合,结果,我脑子里很形象的明白了数组这玩意,所以,我脑子里想像指针也总是想到钟表走动的针……

5):int * p;这个声明是不是同时说明了,指针指向的类型与指针本身的类型是int?指向的类型,我也好理解,因为数据存储方式和占用大小不同,所以要区分,可是指针本身的类型又说明了什么?各种类型的指针占用的内存大小也不同?我电脑里有本叫《C语言深度剖析》的书,说“不管什么样的指针类型,在32位系统下,大小都是4byte”我看过一篇文章说:指针指向的类型与指针自身的类型,是两个概念,不能搞混,是真的吗?那指针本身的类型有什么作用?

6):说老实话,目前来讲,我在看声明的时候,只要在某种类型说明的关键字后面看到 * 这个符号,我心里就有点发毛。我抄出一段话来说明,我为什么心里会发毛。以下:

int * p = NULL;和* p = NULL; 有什么区别?
int *p = NULL;这行代码的意思是:定义一个指针变量p,其指向的内存里保存的是int类型的数据;在定义变量p的同时把p的值设置为0x00000000,而不是把*p的值设置为0x00000000。这个过程叫初始化,是在编译的时候进行的。
然后是
int * p;
*p = NULL;
这两行代码的第一行定义了一个指针变量p,其指向的内存里面保存的是int类型的数据;但是这时候变量p本身的值是多少不知道,可能是非法的地址或者是其它数据的地址,第二行代码是,给*p赋值为NULL,即给p指向的内存赋值为NULL;但是由于p指向的内存可能是非法的,调试的时候编译器可能会报告内存访问错误。

到这里就是书中写的。最前面的语句的功能是不是p的值为NULL?也就是地址,而后面的语句,则是把NULL作为数值存在p所拥有的值,某一地址中,但是,由于p中没有存有地址,所以会有错误。我认为的对吗?它们的区别是不是这样?在int * p = NULL;这行代码中,*起到什么作用,说明变量p是指针变量?还是还有其它的功能? *p = NULL;这条语句,我还能理解,因为*运算符比=高,我抄了一大堆书上写的解释出来,具体还是想问*这个运算符在声明语句的功能,我感觉在书在讲的时候,p 和 *p是两个意思,因为*运算符在表达式语句中不是取指针的值嘛,在声明语句中仅仅是表示某个变量是指针变量吗?而不是普通的某种类型变量,这样理解对吗?

7):我用来自学的书是《C Primer Plus》书中说,数组名是数组首元素的地址。好的,有如下代码:
int array[5] = {1, 2, 3, 4, 5};
int * ptr;
ptr = array;
ptr指向数组array的第一元素,值为1。
然后换到《C语言深度剖析》这本书,作者写道:
&array与&array[0]值虽然相同,但是有区别。array[0]是数组首元素的首地址,而array是整个数组的名字,表示的却是数组首元素的地址。两者只差了一个字,我知道类型的不同,决定了内部的存储方式。但是这种微秒方式会导致某些潜在的问题吗?比如什么取低位字节与高位字节,我听说的,但是不敢肯定,因为我还没理解透,只好猜。

8):指针常量与指向常量的指针两个概念有什么不同?前者是不是 int const * ptr;而后者是const int  const * ptr_one;对吗?不对的话,错在哪?

问题有点多,但基本是我个人理解能力的问题,更多原因,我是想求证,看看我的想法对不对,我没有老师专门教我,我只有电脑里存的电子书,自学不容易啊,而且电脑没有装宽带。求高手帮忙解答一下,感激不尽啊。我怕我会死扣语法或者钻牛角尖,但是还是想搞明白了再继续往下自学,呵呵,麻烦各位了。

回复列表 (共3个回复)

沙发

见lz写这么多,我也顺便谈谈自己的看法,学的很浅,望能学到东西:

在1,2中个人与lz的想法差不多。至于指针,我想意思是明确所指内存的含义吧,呵呵,个人理解。。
①:从5开始吧,int *p;说明p所指类型为int型,如果,只谈个假设,p本身也定义为int型,那float *p;怎么解释?后面32系统中指针长度为4字节,即使void char 型的指针长度也是4字节。所以,指针类型说明其所指元素的类型,而不是其本身类型(至于为什么4字节,这个没学到,猜测和寻址能力有关)。

②:6中lz说的有些问题,“,而后面的语句,则是把NULL作为数值存在p所拥有的值,某一地址中,但是,由于p中没有存有地址,所以会有错误。”p中不是没有存地址,而是地址可能不合法。导致不能访问、、6中后面的内容 int *p;为说明p为指向整型变量指针。

③:7中关于“低位存储”和“高位存储”,只是访问单个字节时会不同,一般来说,一般的存储结构不会影响访问吧、、

④:8中这是不对的,int *const ptr,常量指针\\指针不能修改
int const *ptr或const int *ptr,指向常量的指针。\\常量不能修改
const int * const ptr,指针和指针所指内存的元素都不能修改、、(这是一般而言,其实还是可以绕过去的、、)。
还有就是较新的编译器会忽略多余的const,比如 int const const *ptr,另外,int 和 const的顺序并不重要的。。 

板凳

总的来说,我的想法大部份还算是正确,不枉我挑灯夜读~~感谢这位仁兄

3 楼

加油吧,都是自学,都不容易,而且,我很欣赏坚持自学的人!

我来回复

您尚未登录,请登录后再回复。点此登录或注册