之前可能已经讨论过了。但到目前为止我找不到任何参考。所以想发布它。
当我们声明指针(比如int类型)时,我们写,
int* pointer;
其中int*
是数据类型(因此我们可以执行typedef int* PTR_TO_INT;
,然后可以声明PTR_TO_INT
类型的变量
但是当我们想要声明多个指针时,为什么我们需要为每个指针加上*?
int* pointer1, pointer2, pointer3; // Only first is pointer. Rest are integers
虽然在这种情况下,它的惯例并不相同:
PTR_TO_INT pointer1, pointer2, pointer3; // All are pointers.
示例:
int _tmain(int argc, _TCHAR* argv[])
{
typedef int* PTR_MYINT;
PTR_TO_INT xyz, abc;
int* xyz1, abc1;
xyz = NULL;
abc = xyz; // Valid, as both are pointers
abc1 = xyz1; // Invalid, as abc1 is not pointer
return 0;
}
答案 0 :(得分:9)
这不是“约定”,但语法要求。 *
绑定到右侧令牌(此处为:pointer1
,而不是左侧(此处为:int
)。这就是“惯例”实际写入int *ip
的原因(当您在取消引用指针后再写它以获取它指向的对象时,就像你写的那样)。
所以
int *ip, i;
是两个变量:指向int
(ip
)和int
(i
)的指针。
如果你需要两个指针:
int *ip1, *ip2;
但是为了文档目的,通常建议使用两行注释:
int *ip1; // the first pointer
int *ip2; // points to the next element
此处基类型为int
。如果您有typedef
typedef int *IntPtr;
定义的类型已经是int
的指针,所以如果你使用它作为声明的基类型:
IntPtr ip1, ip2;
你得到两个指针,因为基本类型和上面的例子一样。
警告:这种typedef
在视觉上(即对程序员而不是编译器)隐藏了底层指针语义。这不仅危险,而且还会误导读者,因为你总是要注意这一点。你不应该这样做一般。几乎没有例外,但它们仅用于特殊用例。
注意:另一种查看方式
int *ip;
是:*ip
的类型为int
(对象类型视图)。
答案 1 :(得分:5)
以类似于解除引用运算符*
从右到左的关联性的方式,*
在用于指定类型时严格绑定到 right ,而不是左标记。
因此它与变量名称相关联,而不是类型说明符。
因此,您需要根据个人喜好写出int * pointer1, * pointer2, * pointer3;
的间距。
有效地typedef
规避了这种相关性。
答案 2 :(得分:4)
但是当我们想要声明多个指针时,为什么我们需要为每个指针加上*?
int* pointer1, pointer2, pointer3; // Only first is pointer. Rest are integers
最初写C时最终做出了一个奇怪的决定,这可能是因为能够在同一行代码中创建某些类型的变量和指向这些变量的指针的方便性和简洁性。
int x, *p_x = &x;
当你编写使用大量变量的代码时,在指针和非指针之间相当均匀地混合,这种简洁和便利的好处可以加起来。像C中的许多东西一样,程序员可以选择非常简洁,不同的程序员可能对这是好还是坏有不同的看法。
使用typedef
,您明确为类型创建特定别名,您甚至可能不希望typedef的用户知道它是否最终是指针。例如:
typedef ...something... Handle;
Handle h = awesome_library_init();
awesome_library_finito(h); // never knew if handle was int, struct*...
// may differ on e.g. Linux vs Windows
当鼓励客户程序员将类型视为一些不透明的按值类型时,如果...将会引起混淆......
Handle h1, h2;
...没有创建两个相同类型的相同变量。
答案 3 :(得分:-3)
typedef将*绑定到int(就像在将数据放在某些东西时的数学中一样)。