在C中,声明指针的正确语法是什么?
我依稀记得在回答另一个问题之前看到这个,但search没有得出答案。
我不记得什么是正确的方式来声明variables是指针。 是吗:
Type* instance;
要么:
Type *instance;
虽然我知道在大多数情况下都会编译,但我相信有一些例子很有意义,可能与在同一行中声明多个相同types的variables有关,所以比另一个更有意义。
这只是一个你喜欢阅读的问题。
有人这样说的原因是:
Type *instance;
是因为它说只有实例是一个指针。 因为如果你有一个variables列表:
int* a, b, c;
只有一个是一个指针,所以它更容易
int *a, b, c, *d;
a和d都是指针。 它实际上没有区别,只是可读性。
其他人喜欢*旁边的types,因为(除其他原因之外),他们认为它是一个“指向一个整数”,并认为*属于types,而不是variables。
我个人总是这样做
Type *instance;
但这真的取决于你,以及你的公司/学校代码风格的指导方针。
那两个是一样的 但是,如果你做了多个声明,前者可以陷害你。
int* pi, j;
声明一个int指针( pi )和一个int( j )。
这是C语法的一个意外,你可以用它来写。 然而,它总是被parsing为
Type (*pointer);
也就是说, *总是绑定到声明符,而不是types说明符。 如果你写了
Type* pointer1, pointer2;
它会被parsing为
Type (*pointer1), pointer2;
所以只有pointer1会被声明为一个指针types。
C遵循“声明模仿使用”的范式; 声明的结构应尽可能模仿代码中使用的等同expression方式。 例如,如果您有一个指向int int的指针数组,并且您想要检索数组中的第i个元素所指向的整数值,则可以下标该数组并将其解除引用,结果写为*arr[i] (parsing为*(arr[i]) )。 expression式 *arr[i]是int ,所以arr的声明被写为
int *arr[N];
哪种方式是正确的 ? 取决于你问的问题。 像我这样的老C屁就更喜欢T *p因为它反映了语法中实际发生的事情。 许多C ++程序员都喜欢T* p因为它强调T* p的types,在许多情况下(自己编写了容器types,我可以看到这一点,虽然对我仍然感觉不对),感觉更自然。
如果你想声明多个指针,你可以明确地声明它们,比如:
T *p1, *p2, *p3;
或者你可以创build一个typedef:
typedef T *tptr; tptr p1, p2, p3;
尽pipe我个人不推荐它。 如果你不小心的话,隐藏在typedef后面的东西的指针会咬你。
这两个是完全一样的。
但是,为了声明多个variables,如下所示:
int * p1, p2;
其中p1是指向int的types指针,但是p2的types是int。 如果你想把p2声明为int指针,你必须写:
int *p1, *p2;
我更喜欢以下风格:
Type *pointer;
为什么? 因为它符合语言的创造者所设定的心态:
“variables声明的语法模仿variables可能出现的expression式的语法。”
(由Brian W. Kernighan和Dennis M. Ritchie 编写的C编程语言 ,第94页,版本)
使用任何语言编写FORTRAN都很容易,但是您总是应该使用[编程语言X]编写[编程语言X]。
奇怪的是,这个规则不适用,如果types是在C ++ 0x推导。
int a; decltype(&a) i, j;
我和j都是int *。
所有这些都将编译,是合法的,是相当的:
Type* instance; Type * instance; Type *instance;
select一个风格,并保持一致。
作为一个方面说明,我认为这有助于理解C声明语法背后的动机,这是为了模仿如何使用variables。 下面是一些例子:
-
char *x意味着如果你做*x,你会得到一个char。 -
int f(int x)意味着如果你做例如f(0),你会得到一个int。 -
const char *foo[3]意味着如果你做eg*foo[0](与*(foo[0])),你会得到一个const char。 这意味着foo必须是指向const char的数组(在这种情况下,大小为3)。 -
unsigned int (*foo)[3]意味着如果你做eg(*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];