C 中的指针声明有约定吗?
在 C 中声明指针时,有 3 种变体:
变体 A:
int* ptr;
变体 B:
int *ptr;
变体 C:
int * ptr;
- 在 A 中,间接运算符已附加到类型中。
- 在 B 中,间接运算符已添加到变量前面。
- 在 C 中,间接运算符自由地位于类型和变量之间。
指针的声明方式根据我阅读的文档类型而有所不同。一些作者似乎偏爱某些变体,而另一些作者则使用多种变体。
- 我假设不同变体之间的功能没有差异是否正确?
- 如果是,是否存在在 C 中应使用哪种变体的约定?
When declaring pointers in C, there are 3 variants:
Variant A:
int* ptr;
Variant B:
int *ptr;
Variant C:
int * ptr;
- In A, the indirection operator has been appended to the type.
- In B, the indirection operator has been prepended to the variable.
- In C, the indirection operator stands freely in between type and variable.
The way a pointer is declared differs depending on the type of documentation I read. Some authors seem to have a preference for certain variants, others use several.
- Am I correct to assume that there is no difference in functionality between the different variants?
- If yes, is there a convention for which variant one should be using in C?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
其他人没有提到的是,它
更接近于语言语法。
int *ptr;
是一个声明,其中包含:int
,后跟*ptr
。(这实际上跳过了许多步骤,但它传达了基本思想。)
由于声明遵循使用,这意味着
*ptr
的类型为int
。由此可见,ptr
的类型为int*
。有人可能会争辩说,这比它更好,
出于同样的原因,它
比更好
当然你可以编写
和读取它,因为“
ptr
is of typeint*”
”。许多程序员正是这样做的,并且相处得很好(这往往是 C++ 中的首选风格)。编译器不关心你用哪种方式来做,任何阅读你的代码的人都不应该在理解它时遇到困难。但无论您选择哪种间距,您都需要了解
int *ptr;
的真正含义,这样当您在别人的代码中看到时(您不可避免地会看到),您会立即理解
ptr
是一个指针,i
是一个 int。如果您正在与其他程序员一起开发一个项目,您应该遵循编码标准中现有的任何约定,或者如果没有约定,则应遵循代码的编写方式。与
int* ptr;
相比,我个人更喜欢int *ptr;
,但是混合使用这两种风格比一致使用其中任何一种风格要糟糕得多。Something nobody else has mentioned is that
corresponds more closely to the language grammar.
int *ptr;
is a declaration, which consists of:int
, followed by*ptr
.(That actually skips a number of steps, but it gets the basic idea across.)
Since declaration follows use, what this means is that
*ptr
is of typeint
. It follows from this thatptr
is of typeint*
.One could argue that this makes it better than
for the same reason that
is better than
Of course you can write
and read it as "
ptr
is of typeint*
". And plenty of programmers do exactly that, and get along just fine (it tends to be the preferred style in C++). The compiler doesn't care which way you do it, and anyone reading your code shouldn't have trouble understanding it either way.But whichever spacing you choose, you need to understand what
int *ptr;
really means, so that when you seein someone else's code (as you inevitably will), you'll immediately understand that
ptr
is a pointer andi
is an int.And if you're working with other programmers on a project, you should follow whatever existing convention is in the coding standards, or if there isn't one, the way the code is already written. I personally prefer
int *ptr;
toint* ptr;
, but using a mixture of both styles is far worse than using either one consistently.是声明指向
T
的指针的首选 C 风格,如 Kernighan & 中所使用的那样。 Ritchie 关于 C 的书,以及 ISO/IEC 9899:2018 中的书。是声明指向
T
指针的首选 C++ 风格方式,如 Stroustrup 关于 C++ 的书中所使用的那样。两种表示法是等效的。
is the preferred C style for declaring a pointer to
T
as used in Kernighan & Ritchie's book about C, as well as in ISO/IEC 9899:2018.is the preferred C++ style way to a declare pointer to
T
as used in Stroustrup's book about C++.Both notations are equivalent.
之间的功能绝对没有区别
,
您使用哪种取决于您,有多种相互冲突的编码风格可供选择。
There is absolutely no difference in functionality between
and
Which you use is up to you, there are multiple conflicting coding styles to choose from.
它们的意思与其他人所说的相同。但有一个陷阱在等着你。考虑以下代码:
您可能认为 this 声明为指向
int
的指针。不是这样,但除此之外。事实上,a
是int*
,但b
是int
。这是许多 C 程序员更喜欢将*
放在变量而不是类型旁边的原因之一。当这样写时:您不太可能被误导到
a
和b
是什么。话虽如此,许多编码标准坚持要求每行声明不超过一个变量,即
如果您遵循每行一个变量的规则,那么绝对不会产生混淆。
They both mean the same as others have said. There is a trap waiting for you though. Consider this code:
You might think that this declared to pointers to
int
. No so but otherwise. In facta
isint*
butb
isint
. This is one of the reasons for many C programmers preferring to put the*
next to the variable rather than the type. When written like this:you are less likely to be misled as to what
a
andb
are.Having said all that, many coding standards insist that you declare no more than one variable per line, i,e.
If you follow the one variable per line rule then there is definitely no scope for confusion.
仅当您计划在同一行声明相同类型的多个变量时,这才重要。例如,如果您想要多个 int 指针,则需要这样做:
但从风格上讲,当您仅声明单个变量时,这会令人困惑。许多人喜欢看到类型后跟变量名,并且类型应该是指向 int 的指针,而不是 int,因此他们更喜欢:
最终取决于您是否更喜欢一种形式而不是另一种形式。在 20 年的 C 专业编程生涯中,我看到大约 50% 的人选择其中一种。
It matters only when you plan to declare multiple variables of the same type on the same line. For example, if you want multiple int pointers, you need to do this:
Stylistically though, this is confusing when you're only declaring a single variable. Many people like to see the type followed by the variable name, and the type is supposed to be pointer to int, not int, so they prefer:
It's ultimately up to you whether you prefer one form over the other. In 20 years of programming C professionally, I've seen about 50% of people choose one over the other.
C 声明基于表达式的类型,而不是对象。
如果您有一个指向名为
pi
的int
的指针,并且想要访问它指向的整数值,则必须取消引用该指针,如下所示:等等。 表达式
*pi
的类型是int
:因此,声明应读为现在让我们假设您有一个指向
的指针数组>字符;要获取任何字符,您需要首先在数组中添加下标,然后取消引用结果:
等等。同样,表达式
*pc[i]
的类型为 < code>char,因此声明读作*pi
和*pc[N]
都称为声明符,并指定类型说明符未给出的附加类型信息。 IOW,pc
的数组性质和指针性质被指定为声明符的一部分,而char
性质由类型说明符给出。至于哪种风格是正确的问题...
两者都不是“正确的”,但我(和许多其他 C 程序员)更喜欢将
T *p
写为与T* p
相反,因为它更准确地反映了语言语法(*
是声明符的一部分),并且有助于避免声明多个项目时出现混淆。我见过太多的例子,人们编写T* a, b;
并期望b
是一个指针。对这种批评的通常回应是“每行不要声明多个项目”。我对此回应的回应是“正确编写你的声明符,你不会有任何问题”。
许多 C++ 程序员有不同的思想流派,他们更喜欢
T* p
风格,我不得不说,在某些情况下(仅限于 C++)它可以 使代码更具可读性。然而,这只适用于简单的指向
T
的指针:当您开始处理指针数组、指向数组的指针、指向函数的指针、或者指向函数指针数组的指针时,这种范式很快就会崩溃。等等。我的意思是,写类似的东西只是表明思维混乱。不过,如果您真的真的觉得您必须遵循
T* p
范例,那么您总是可以创建一系列类型定义:>编辑
让我们再试一次:
看在上帝的份上,不要那样做。
C declarations are based around the types of expressions, not objects.
If you have a pointer to an
int
namedpi
, and you want to access the integer value that it points to, you have to dereference the pointer, as in:etc. The type of the expression
*pi
isint
: therefore, the declaration should read asNow let's suppose you had an array of pointers to
char
; to get to any character, you need to first subscript into the array, then dereference the result:etc. Again, the type of the expression
*pc[i]
ischar
, so the declaration reads asBoth
*pi
and*pc[N]
are known as declarators, and specify additional type information not given by the type specifier. IOW, the array-ness and pointer-ness ofpc
are specified as part of the declarator, while thechar
-ness is given by the type specifier.As to the question of which is style is proper...
Neither one is "right", but I (and many other C programmers) prefer to write
T *p
as opposed toT* p
, since it more closely reflects the language grammar (the*
is part of the declarator) and it helps avoid confusion when declaring multiple items. I've seen far too many examples of people writingT* a, b;
and expectingb
to be a pointer.The usual response to that criticism is "don't declare more than one item per line." My response to that response is "write your declarators correctly and you won't have any problems".
There's a different school of thought among many C++ programmers, who prefer the
T* p
style, and I have to say there are a few cases (limited to C++) where it can make the code more readable.However, that only works for simple pointers to
T
: the paradigm rapidly breaks down when you start dealing with arrays of pointers, or pointers to arrays, or pointers to functions, or pointers to arrays of pointers to functions, etc. I mean, writing something likejust indicates confused thinking. Although, if you really really really feel that you must follow the
T* p
paradigm, you could always create a series of typedefs:EDIT
Let's try that again:
For the love of God, don't do that.
在 C 中,除非需要分隔标记,否则空格并不重要。您的两种变体在语法上都是正确的。
变体 1 将指针运算符与类型相关联,这是足够合乎逻辑的。对我来说,如果没有因为变体 2 有意义的原因,这就足够了。
变体 2 与 C 声明的结构方式一致。在 C 语法中,指针运算符属于声明符(即名称),而不是类型。当在同一个声明中声明多个变量时,这一点很重要。还有一些更深奥的案例也很重要。
因此,对我来说,变体 2 与 C 更一致。但任一变体都是合理的,并且两种变体都是常规的。
In C, whitespace does not matter except where it is needed to separate tokens. Both your variants are syntactically correct.
Variant 1 associates the pointer operator with the type, which is logical enough. For me, that would be enough if there wasn't for the reason why Variant 2 makes sense.
Variant 2 is consistent with the way C declarations are structured. In the C grammar, the pointer operator belongs in the declarator (that is, with the name), not the type. This matters when declaring multiple variables in the same declaration. There are also a number of more esoteric cases where it matters.
Thus, for me, Variant 2 is more consistent with C. But either variant is defensible, and both variants are conventional.
你是对的,两者对编译器来说意味着完全相同的事情。这两个语句都会生成一个
(int *)
类型的变量。至于哪个是正确的:蠕虫罐头!
这通常是一个辩论话题。如果您在公司或 OSS 工作,最好遵循定义的编码风格。如果没有,我通常会使用 LNT(不留痕迹)风格来匹配这部分代码库中明显使用的任何风格。
可以说,对于读者来说,更容易理解。例如,
int* ptr;
将*
置于更接近int
的位置,这样可以更清楚地传达我们正在讨论的(int * )
输入...You are correct, both mean exactly the same thing to the compiler. Both statements will produce a variable of type
(int *)
.As for which is correct: Can of worms!
That is a debate topic usually. If you work for a company or on OSS, it's probably best to defer to a defined coding style. If there isn't one I usually go the the LNT (leave no trace) style of matching whatever style has evidentially been used in this part of the code base.
It can be argued that to the reader one is easier to understand. For example
int* ptr;
puts the*
closer to theint
which more clearly communicates the we are talking about an(int *)
type...