关于c ++:指针声明中星号的位置

您所在的位置:网站首页 指针const三个位置 关于c ++:指针声明中星号的位置

关于c ++:指针声明中星号的位置

2024-07-03 16:24| 来源: 网络整理| 查看: 265

最近,我决定只需要最终学习C / C ++,关于指针,或者更确切地说,它们的定义,我并没有真正了解的一件事。

这些示例如何:

int* test; int *test; int * test; int* test,test2; int *test,test2; int * test,test2;

现在,据我所知,前三个案例都在做同样的事情:Test不是一个int,而是一个指向int的指针。

第二组示例比较棘手。 在情况4中,test和test2都是指向int的指针,而在情况5中,只有test是一个指针,而test2是"真实" int。 情况6呢? 与情况5相同?

相关讨论 在C / C ++中,空格不会改变含义。 7. int*test;? +1是因为Id只想问关于1-3的问题。阅读此问题使我了解到Id从未想过的关于4-6的问题。 @Sulthan 99%的时间是正确的,但并非总是如此。在我脑海中,有一个模板类型空间要求(C ++ 11之前)中的模板类型。在Foo>中,必须将>>写入> >,以免被视为右移。 @AnorZaken你是对的,多数民众赞成在一个相当老的评论。在多种情况下,空间将发生变化,例如,增量++运算符不能用空格分隔,标识符不能用空格分隔(并且结果对于编译器仍然合法,但具有未定义的运行时行为) )。考虑到C / C ++的语法混乱,很难定义确切的情况。 @Sulthan是的,您现在提到的那些情况应该很明显,我的意思是,有一些非显而易见的情况需要空格。无论如何,我只想将该笔记记录下来,但这并不意味着批评您的评论。

4、5和6是同一件事,只是测试是一个指针。如果要两个指针,则应使用:

1int *test, *test2;

或者,甚至更好(使一切清晰):

12int* test; int* test2; 相关讨论 那么案例4实际上是一个死亡陷阱吗?有没有说明或解释为什么int * test,test2仅使第一个变量成为指针的规范? @ Michael Stum它的C ++语言,您真的认为这是合乎逻辑的解释吗? 阅读K&R(C编程语言)。它非常清楚地解释了所有这些。 注意,几乎每个人都推荐这本书,然后就从亚马逊那里抢了本书。但是现在至少我记得为什么我过去不愿意选择C / C ++了:-) 案例4、5和6是"死亡陷阱"。这就是为什么许多C / C ++样式指导建议每个语句仅一个声明的原因之一。 空格对于C编译器而言无关紧要(忽略预处理器)。因此,无论星号和其周围有多少空间或周围有多少,它的含义都完全相同。

星号周围的空白不重要。这三个意思相同:

123int* test; int *test; int * test;

" int *var1, var2"是一种邪恶的语法,仅用于使人感到困惑,应避免使用。它扩展为:

12int *var1; int var2; 相关讨论 不要忘记int*test。 星号之前或之后的空间只是美学问题。但是,Google Coding标准与int *test一起使用(google-styleguide.googlecode.com/svn/trunk/)。保持一致 @SebastianRaschka《 Google C ++样式指南》明确允许使用任何一个星号放置。自您阅读以来,它可能已更改。

使用"顺时针螺旋规则"有助于解析C / C ++声明;

There are three simple steps to follow:

Starting with the unknown element, move in a spiral/clockwise direction; when encountering the following elements replace them with the corresponding english statements:

[X] or []: Array X size of... or Array undefined size of...

(type1, type2): function passing type1 and type2 returning...

*: pointer(s) to...

Keep doing this in a spiral/clockwise direction until all tokens have been covered. Always resolve anything in parenthesis first!

同样,在可能的情况下,声明应放在单独的语句中(在大多数情况下是这样)。

相关讨论 遗憾的是,这看起来令人生畏并且非常可怕。 确实如此,但是对于一些更复杂的结构似乎是一个很好的解释 @ d03boy:毫无疑问-C / C ++声明可能是一场噩梦。 "螺旋"没有任何意义,更不用说"顺时针"了。宁愿将其命名为"右-左规则",因为语法不会使您看起来从右下-左上,仅右-左。 我将其学习为"左右左右"规则。 C ++人士经常喜欢假装所有类型信息在左侧,这导致了int* x;样式,而不是传统的int *x;样式。当然,间距对编译器来说并不重要,但确实会影响人类。拒绝实际语法会导致样式规则,这些规则会使读者感到烦恼和困惑。

许多编码指南建议您每行仅声明一个变量。这样可以避免您在问这个问题之前感到困惑。与我合作的大多数C ++程序员似乎都坚持这一点。

我知道一点,但我发现有用的是向后读取声明。

1int* test;   // test is a pointer to an int

这开始工作得很好,尤其是当您开始声明const指针时,要弄清是指针是const还是指针所指向的东西是const变得很棘手。

1234int* const test; // test is a const pointer to an int int const * test; // test is a pointer to a const int ... but many people write this as   const int * test; // test is a pointer to an int that's const

如其他提到的,4,5和6是相同的。通常,人们使用这些示例来说明*属于变量而不是类型。尽管这是样式问题,但对于您是否应该以这种方式思考和编写它存在一些争论:

1int* x; //"x is a pointer to int"

或者这样:

1int *x; //"*x is an int"

FWIW我在第一阵营,但是其他人为第二种形式争论的原因是(主要)它解决了这个特定问题:

1int* x,y; //"x is a pointer to int, y is an int"

这可能会产生误导;相反,你会写

1int *x,y; // it's a little clearer what is going on here

或者如果您真的想要两个指针,

1int *x, *y; // two pointers

就我个人而言,我说将其保留为每行一个变量,那么您喜欢哪种样式都没有关系。

相关讨论 这是假的,您怎么称呼int *MyFunc(void)? *MyFunc是返回int的函数吗?没有。显然,我们应该编写int* MyFunc(void),并说MyFunc是一个返回int*的函数。因此,对我来说很明显,C和C ++语法解析规则对于变量声明完全是错误的。它们应该已经将指针限定符作为整个逗号序列的共享类型的一部分。 但是*MyFunc()是int。 C语法的问题在于混合使用前缀和后缀语法-如果仅使用后缀,则不会造成混淆。 第一个阵营与语言语法作斗争,导致诸如int const* x;之类的令人困惑的结构,我发现它与a * x+b * y一样具有误导性。

123#include std::add_pointer::type test, test2; 相关讨论 #include LPINT test, test2;

在4、5和6中,test始终是指针,而test2不是指针。在C ++中,空格几乎(几乎)不重要。

我认为,最好将星号放在指针名称旁边,而不是类型旁边。比较例如:

123int *pointer1, *pointer2; // Fully consistent, two pointers int* pointer1, pointer2;  // Inconsistent -- because only the first one is a pointer, the second one is an int variable // The second case is unexpected, and thus prone to errors

为什么第二种情况不一致?因为例如int x,y;声明两个相同类型的变量,但在声明中仅提及一次该类型。这创建了先例和预期行为。并且int* pointer1, pointer2;与此不一致,因为它将pointer1声明为指针,但是pointer2是整数变量。显然容易出错,因此应避免(通过在指针名称而不是类型旁边放置星号)。

但是,在某些例外情况下,您可能无法在没有得到不希望的结果的情况下将星号放在对象名称旁边(并且在您放置它的位置很重要)—例如:

MyClass * volatile MyObjName

指针是该类型的修饰符。最好从右到左阅读它们,以更好地理解星号如何修改类型。" int *"可以理解为"指向int的指针",在多个声明中必须指定每个变量都是一个指针,否则它将被创建为标准变量。

1,2和3)测试的类型为(int *)。空格无关紧要。

4,5和6)测试属于(int *)类型。 Test2是int类型的。同样,空格是无关紧要的。

我会说最初的约定是将星形放在指针名称的一侧(声明的右侧)。

在Dennis M. Ritchie的c编程语言中,星星在声明的右侧。

通过查看https://github.com/torvalds/linux/blob/master/init/main.c上的linux源代码 我们可以看到星星也在右边。

您可以遵循相同的规则,但是如果在类型方面放星星,则没什么大不了的。 请记住,一致性很重要,因此无论选择哪一面,始终保持恒星不变。

C语言的基本原理是您以使用变量的方式声明变量。例如

1char *a[100];

说*a[42]将是char。和a[42]一个char指针。因此a是一个char指针数组。

这是因为原始的编译器作者希望对表达式和声明使用相同的解析器。 (选择语言设计不是很明智的原因)

相关讨论 然而,编写char* a[100];也会推断出*a[42];将是char,而a[42];将是char指针。 好吧,我们都得出相同的结论,只是顺序是变化的。 Quote:"说* a [42]将是一个字符。而a [42]将是一个字符指针"。 您确定不是相反吗? 如果您更喜欢另一种方式,则说a[42]是char指针,而*a[42]是字符。

您可以将4、5和6视为: 声明类型只需要执行一次,但是如果要声明指向该类型的指针(通过添加星号),则必须对每个变量进行声明。

声明指针变量时,即使在一行中声明多个,我也总是在变量和星号之间添加空格。否则,几乎每次都使我感到困惑。

情况1、2和3相同,它们声明了指向int变量的指针。情况3、4和5相同,因为它们分别声明了一个指向的指针和一个int变量。如果要在一行中声明两个指针(不应该声明),则需要在每个变量名称的前面放置一个星号:

1int *test, *test2;

没有特定的正确方式说明星号的位置。 int* test看起来更好,因为我们更容易想象将*附加到类型的末尾意味着该类型的"指针"。但是,int *test更有意义,因为您可以像数学中的减号一样使用它:

1-(-x) = x

类似于

1*(*test) = test

这一直对我有帮助。可悲的是,这一切的结果是有时我使用int* test,有时使用int *test。

相关讨论 **测试肯定与测试不同。 *&test与test相同。括号没有区别。 (实际上,由于单个等号是赋值而不是相等,因此带有负号的示例也不起作用)。 最后一条语句不是C代码(没有分号),只是为了说明如果您声明int * test,然后对其使用解引用运算符,将会发生什么。在c中,应为" int * test; int i = * test;"。双减号示例也不是C代码(同样也不是分号),而是一个数学示例,在我看来,它很好地工作了。 为什么不应该在同一声明中声明两个指针的原因是什么? int *a, b;或int *a, *b;甚至不会让像样的C程序员感到困惑

一个好的经验法则是,许多人似乎通过以下方式来掌握这些概念:在C ++中,许多语义是通过关键字或标识符的左键绑定而得出的。

举个例子:

1int const bla;

const适用于" int"一词。指针的星号也是如此,它们适用于它们左侧的关键字。以及实际的变量名?是的,这是用剩下的来声明的。

相关讨论 这没有回答问题。更糟糕的是,如果我们尝试从中推断出答案,则意味着星号绑定到其左侧的类型,正如其他人所说的那样,它是错误的。它绑定到其右侧的单个变量名称。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3