在C中,声明指针的正确语法是什么?

时间:2010-07-19 11:45:45

标签: c syntax pointers variables types

我模糊地回忆起在回答另一个问题之前看到这个问题,但是搜索未能得出答案。

我不记得什么是正确的方式来声明作为指针的变量。是吗:

Type* instance;

或者:

Type *instance;

虽然我知道两者都会在大多数情况下编译,但我相信有一些例子很重要,可能与在同一行上声明同一类型的多个变量有关,因此一个比另一个更有意义。< / p>

8 个答案:

答案 0 :(得分:24)

这只是你喜欢读它的问题。

有些人之所以这么说:

Type *instance;

是因为它说只有实例是一个指针。因为如果你有一个变量列表:

int* a, b, c;

只有a是一个指针,所以它更容易这样

int *a, b, c, *d;

a和d都是指针。它实际上没有区别,只是可读性。

其他人喜欢在类型旁边使用*,因为(除其他原因外)他们认为它是“指向整数的指针”,并认为*属于类型,而不是变量。

我个人经常

Type *instance;

但这取决于您和您的公司/学校代码风格指南。

答案 1 :(得分:11)

这两个是相同的。但是,如果你做了多个声明,前者可能会陷阱。

int* pi, j;

声明一个int指针(pi)和一个int(j)。

答案 2 :(得分:7)

这是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后面的东西的指针可能会咬你。

答案 3 :(得分:3)

这两者完全一样。

但是,为了声明多个变量,如下所示:

int * p1, p2;

其中p1是指向int的类型指针,但p2的类型为int。如果您希望将p2声明为指向int的指针,则必须编写:

int *p1, *p2;

答案 4 :(得分:2)

我更喜欢以下风格:

Type *pointer;

为什么呢?因为它符合心态,语言的创造者试图建立:

  

“变量声明的语法模仿了变量可能出现的表达式的语法。”

     

The C Programming Language作者:Brian W. Kernighan&amp; Dennis M. Ritchie,ansi c version,page 94)

用任何语言编写FORTRAN都很容易,但你总是应该在[编程语言X]中编写[编程语言X]。

答案 5 :(得分:1)

奇怪的是,如果在C ++ 0x中推断出类型,则此规则不适用。

int a;
decltype(&a) i, j;

i和j都是int *。

答案 6 :(得分:1)

所有这些都将编译,是合法的并且是等效的:

Type* instance;
Type * instance;
Type *instance;

选择一种风格并保持一致。

答案 7 :(得分:0)

作为旁注,我认为理解C声明语法背后的动机是有帮助的,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必须是指向unsigned int数组的指针(在这种情况下大小为3)。

因此,一般语法是[what you get] [how you get it]。诀窍是,这可以扩展到[what you get] [how you get it], [how you get it], ...以同时声明多个事物。因此,以下三个声明 -

int *p;
int f(int x);
int a[3];

- 可以按如下方式组合成一行(是的,这甚至适用于函数声明。在这方面它们并不特别):

int *p, f(int x), a[3];