这只是为了编译器做类型安全检查,同时也为了正确引用指向的空间
不只是多级指针可以像你说的那样定义(当然需要强制转换),即使是不同类型的指针也可以以一种方式定义(还是需要强制转换),比如所有指针都定义成int *(或者任何和指针长度一样的变量也可以,也就是你说的都可以装),但是这需要程序员自己检查类型安全(比如,不能出现把struct当int使)。当工程大了之后很容易出现安全问题,是不可取的。下面举个例子:
1)安全用法
int ** p;
int *a;
int b;
p = &a;//right
p = &b;//error,编译器会告诉你类型不匹配,依赖编译器进行检查,编译器永远知道你把这个指针当何种类型用
2)不安全用法
int *p;//用做int **
int *a;//用作int*
int b;
(int **)p = &a;//right
p = &b;//不报错,但是不符合你的本意。有时候你难免会忘记进行强制转换 ,甚至时间长了还会忘记当初的本意,跟别人合作时别人也不知道你的本意,也就根本没有人知道当初你打算把它当何种类型用了
另外,程序中一般不会出现3级或更多级指针,当你都不知道有多少级的时候我想你也就不明白为什么要用那么多级了,也就用不着。
第一个问题,单从存储空间上来说是可以的,但是如果这样做的话很容易混淆,所以c编译器是不支持这样的,
第二个问题,是这样的,编译器不报错,但是不建议嵌套多层。。。
第三个问题,地址确实都是一样的。如果你接触过汇编的话就容易理解了,cpu执行指令的时候需要知道操作数是什么类型的来取数据,而地址占的存储空间,和各种数据类型占得存储空间也是随操作系统的不同而不同的。你直接给个地址的话,是没办法知道根据这个地址是要取一个字节的内容呢,还是取一个字的内容,或者是两个字的内容,所以要先定义好。
下面的问题,如果上面的你看明白了,就不是问题了。
希望你可以明白,不明白再问吧
呵呵c语言指针是个最让人晕的了,即使你是个C语言程序高手,你也不敢肯定你就能随心所欲运用指针。
好吧,我先不跟你说指针的感念,现在我要你忘记指针的概念。把指针当作一个4字节的无符号整型数看,比如unsigned long。OK,现在没有指针的概念了,就是一个4字节的空间罢了,我给这个4字节空间取个名字,就a把。好现在我们回过头来看什么是指针,我在给领一个4字节的空间取个名字就b把。现在指针是什么呢,就是一个4字节空间的a,它不存放比如4,5之类的数据内容,而是存放另一个4字节空间b的地址。好现在我们看看什么是多级指针,我们在取个4字节空间c,我们让这个c寸a的地址,那么c就是我们说的二级的指针了。说白了就是c这个指针可以操作两个空间,*号取内容一下就可以操作a啦,在*号取内容一下就可以操作b啦。
所以说指针只是人为定义的一个索引数据的工具罢了,现在我们回过来看你说的问题,为什么不用一级指针指向一个指针的地址,首先这个是可以的,但是一级指针指向指针地址后,他就只能操作指针而不能操作指针指向的变量了。
嗯就像上面举的例子一样,c就只能操作a而不能操作a指向的b了。
嗯关键是理解指针只是一种索引数据的工具而已,多级指针就是多级索引。形象点就像书的目录一样,多级目录就能索引很多级,而一级目录就只能索引一级啦
为什么用**p 而不用*p可以这样理解:定义指针的时候, 数据类型 *指针变量名,如 int *p;这就说明p是一个指针,指向的是一个int类型的数据。二级指针 如 int **p则表示:定义了一个二级指针变量p,指向的是一个指针类型的数据,它所指向的这个指针类型的数据(即*p)所指向的是int类型的数据。
指针一般用一级、二级指针,三级的没见过,真要用可以像***p 这样定义,n级n个*
int main()
{
int num = 9;
int *a = #
int **b = &a;
int ***c = &b;
cout<<***c;
return 0;
}
这个程序可以运行出正确结果,输出 9。
int main()
{
int num = 9;
int *a = #
int **b = &a;
int ***c = &a;//int ***c = &b;
cout<<***c;
return 0;
}
这个程序运行出错,因为它把一级指针的地址赋给三级指针。三级指针只能指向二级指针的地址。
虽然指针都是地址,但编译器知道什么样的指针变量存放什么样的地址
整形变量存放整形数据,不能存地址,你看不出区别,编译器看的出来。。。。。
一般用不到三级及以后的指针。。。
*q 表示指针p的地址,那指针p对应的变量怎么表示呢!只能用指针的指针来表示啊