2014-10-30 57 views
0

因此,这里是一个锻炼和,给出以下解决方案:了解指针和地址引用用C

假设下面的声明已经做出:

char c = ‘A’; 
char *p = &c; 
char **p2 = &p; 
void *v = &p2; 

检查每个以下表达式。如果该表达式是非法的,写入ILLEGAL。如果表达式是合法的,请写下它的类型(即int,void *等)

&p2 : char*** 
*p2: char* 
&v: char**** 
p2 + 1: char** 
v[0]: Illegal 

您能解释我们如何得到这样的类型吗?我知道v [0]是非法的,因为v指向地址,我们不能像使用数组那样使用括号表示来访问它。 但所有其他让我有点困惑,尤其是1-3。

我很乐意帮忙!

+0

>我们不能使用括号表示来访问 - 为什么不呢? v [0] == *(v + 0)。 – someuser 2014-10-30 04:02:12

+0

实际上,'v [0]'是不合法的,因为'v'是一个指向'void'的指针,并且'void'的指针可能不会被解引用。要引用K&R,“无效对象的(不存在)值可能不会以任何方式使用......” – user3386109 2014-10-30 04:04:46

+0

@ user3386109,通常我们可以使用这个表示法来访问 - 这就是我想说的。 – someuser 2014-10-30 04:07:00

回答

0

先从基本变量

c: char 
p: char* (because p = &c) 
p2: char** (because p2 = &p) 
v: char*** (because v = &p2) 

现在,&增加了一个间接层,并*解引用,其中减去一个间接层。

&p2: char*** (because p2 is char**) 
*p2: char* (because p2 is char**) 
&v: char**** (because v is char***) 
p2 + 1: char** (same type as p2) 

注意,你可以(有些人)写char *pchar* p它可以更容易地翻译成“char*类型的变量p”,同为char** p等,但char *p已经俨然成为了惯例。当我加入遵循char *p公约的公司时,我个人很难转换。

+0

只有'void *',没有进一步的间接寻址,因为'void *'实质上是指“一个指针(对任何事物)”,“一个指针指向任何事物”仍然是一个指针。你实际上可以将任何指针类型(比如'char *','char **','char ***'等)转换为'void *'。但是在使用'void *'之前,它通常会变成更具体的东西。 – 2014-10-30 04:14:49

+0

我认为该惯例是为了允许在一行上进行多个声明,例如'char * a,* b;'。行'char * a,b;'声明'a'为一个指针,'b'声明为一个简单的'char'。 – user3386109 2014-10-30 04:15:51

+0

@ user3386109同意。我很少在同一行上声明变量(实际上90%的时间是用默认值初始化的)。仍然Objective-C通过了公约,所以现在我只是按照没有问题:) – 2014-10-30 04:22:06

3

对于T类型的任何左值表达式e,表达&e具有类型T *,和表达式的值是e位置。类似地,对于类型T *的任何表达式p,表达式*p具有类型T并且表达式的值是任何p指向的值。

表达c具有类型char,所以表达式&c具有类型char *,和表达式的值是c位置。该值被分配给变量p,其中也有键入char *

由于p已键入char *,表达&p的类型为char **和的值是p位置。这被分配给变量p2,其也具有类型char **

答案键有错误; &v 的类型是void **,而不是char ****

v[0]是非法的,因为v的类型为void *,并且您不允许取消引用void指针。