我模糊地记得之前在另一个问题的回答中见过这个,但搜索没有得到答案。
我不记得声明指针变量的正确方法是什么。是这样吗:
Type* instance;
或者:
Type *instance;
虽然我知道在大多数情况下这两种方式都可以编译,但我认为有一些例子是很重要的,可能与在同一行声明多个相同类型的变量有关,因此其中一种比另一种更合理。
这仅仅取决于你更喜欢怎样阅读。
有些人之所以会这样表达:
Type *instance;
是因为代码说只有实例(instance)才是指针(pointer)。如果你有一组变量:
int* a, b, c;
只有a是指针,所以这样更容易
int *a, b, c, *d;
其中a和d都是指针,实际上没有区别,只是为了可读性。
其他人喜欢将*放在类型旁边,因为(除其他原因外)他们认为它是“指向整数的指针”,并认为*应该与类型一起出现,而不是变量。
个人来说,我总是这样做
Type *instance;
但这确实取决于你以及你公司或学校的代码风格指南。
int* a,b,c
会让人感到困惑,因此如果没有其他指导方针,我会使用 Type *instance
。 - Eddint *
,在C++中使用int*
。在C++中,一般最好逐个声明标识符,因此参数“int* a, b, c
是蓬松的”意义不大。类型系统的一致性在C++中更是一个重要问题。 - Alexandre C.这两者是相同的。然而,如果您进行多次声明,前者可能会使您陷入困境。
int* pi, j;
声明了一个int指针 (pi
) 和一个int (j
)。
在C语言中,你可以以两种方式编写它,但是它总是被解析为
Type (*pointer);
也就是说,*
符号总是绑定到声明符上,而非类型说明符。如果你写成
Type* pointer1, pointer2;
如果需要解析,它会被解析为
Type (*pointer1), pointer2;
因此,只有pointer1被声明为指针类型。
C遵循“声明模仿使用”的范例;声明的结构应该尽可能地模仿代码中使用的等效表达式。例如,如果你有一个名为arr
的指向int类型的指针数组,并且你想要检索数组中第i个元素指向的整数值,你会对数组进行下标运算并解引用结果,写作*arr[i]
(解析为*(arr[i])
)。表达式*arr[i]
的类型是int
,因此arr
的声明被写成:
int *arr[N];
这离右边近还是左边近?这要看问谁了。像我这样的老旧C工程师喜欢使用T *p
,因为它反映出语法实际发生的情况。许多C++程序员更喜欢T* p
,因为它强调了p
的类型,在许多情况下感觉更自然(我自己写了容器类型后,也能明白这一点,尽管仍然感觉不对)。
如果您想声明多个指针,可以全部明确声明,例如:
T *p1, *p2, *p3;
或者您可以创建一个 typedef:
typedef T *tptr;
tptr p1, p2, p3;
虽然我个人不推荐这样做;但是,如果你不小心隐藏了某个东西的指针性质,那么使用typedef可能会给你带来麻烦。
MyClassPtr
比编写boost::shared_ptr<MyClass>
要快得多。 - Pedro d'Aquino(*it)->foo()
而不是 it->foo()
,但是由于迭代器被声明为 vector<a_typedef_name_that_doesn't_indicate_pointerness_AT_ALL>::iterator
而不是 vector<T*>::iterator
,你没有意识到需要额外的解引用。那个下午并不是最有效率的。 - John Bode这两个完全相同。
然而,在声明多个变量的情况下,如下所示:
int * p1, p2;
p1是指向整型的指针类型,而p2是整型类型。如果您希望将p2声明为指向整型的指针,您需要编写:
int *p1, *p2;
Type *pointer;
Type* instance;
Type * instance;
Type *instance;
有趣的是,在C++0x中如果类型可以被推断,则不适用此规则。
int a;
decltype(&a) i, j;
变量 i 和 j 都是 int* 类型。
typedef int *IntPtr;
,然后 IntPtr i, j;
就可以展示相同的行为。 - Philipp顺便说一下,我认为理解C语言声明语法背后的动机很有帮助,这是为了模拟变量的使用方式。以下是一些示例:
char *x
表示如果你执行 *x
,你会得到一个 char
。int f(int x)
表示如果你执行例如 f(0)
,你会得到一个 int
。const char *foo[3]
表示如果你执行例如 *foo[0]
(与 *(foo[0])
相同),你会得到一个 const char
。这意味着 foo
必须是一个指向 const char
的指针数组(在这种情况下大小为3)。unsigned int (*foo)[3]
表示如果你执行例如 (*foo)[0]
,你会得到一个 unsigned int
。这意味着 foo
必须是一个指向大小为3的 unsigned int
数组的指针。大致上,一般的语法是这样的:[你得到什么] [你如何得到它]
。诀窍在于,这可以扩展为[你得到什么] [你如何得到它],[你如何得到它],...
以一次声明多个事物。因此,以下三个声明--
int *p;
int f(int x);
int a[3];
-- 可以合并为一行,如下所示(是的,这甚至适用于函数声明。在这方面它们并不特殊):
int *p, f(int x), a[3];