【问题标题】:Whats the difference between float* varname and float *varname in classic c经典c中float * varname和float *varname有什么区别
【发布时间】:2010-01-24 22:59:36
【问题描述】:

float* varname 和 float *varname 在经典 C 中的区别是什么?

【问题讨论】:

  • 没有区别,无论哪种方式编译器都很高兴。 'C' 程序员倾向于在类型名称后使用空格,这样在声明多个变量时会减少混淆。这必须是骗人的。
  • 你打开了一个宗教的蠕虫罐头。 :) 我很惊讶到目前为止的大多数答案都是温和的。
  • 这不是昨天问的,而是int 是类型吗?昨天的问题是重复的重复?
  • 请给我看看骗子,我没找到
  • @James 和@Peanut:确实以前有人问过。但是很难搜索它们,除非您碰巧猜到了示例中使用的变量名称。然而,这是上周的一个:stackoverflow.com/questions/2065232。您可以通过从该帖子中递归抓取来找到其他重复项!

标签: c syntax


【解决方案1】:

格式化。而已。它们的意思是一样的。

你把空间放在哪里(或者如果你有一个,真的)是一个偏好问题。有些人更喜欢 varname 旁边的 *,这样您就不会被以下内容混淆:

float* a, b;

(这里只有a是指针,b不是)

其他人认为他们从不一次声明多个变量,因此他们更喜欢浮动旁边的 *,因为它是类型的一部分。

【讨论】:

  • 有人想知道那些将* 放在float 旁边的人是如何设法声明数组的。
  • 不过,您仍然不能将 [N] 放在类型的其余部分旁边。
  • @caf:这就是为什么我发现整个“它描述了类型”的论点似是而非,因为它与其他所有类型不一致;每次我看到int* a[10];double* foo(); 之类的东西时,我都会感到困惑。
  • @caf:当然可以。如果你说template <typename T> struct identity { typedef T type; };,那么你可以说identity<int[10]>::type numbers;,这会将[N] 部分放在类型旁边。
  • @FredOverflow:这是 C 语言中一个严重的语法错误,这个问题专门针对“经典 C”。
【解决方案2】:

没有区别。空格被完全忽略。

但请注意,以下内容可能具有误导性:

float* var1, var2;

对上述内容的随意检查会导致您认为 var1 和 var2 都是指向浮点数的指针。但是你错了,因为这将 var1 声明为指向浮点数的指针,但 var2 将是一个常规浮点数。

【讨论】:

  • 有趣的是,C 认为 * 更多地与变量名相关联,而不是与指向类型的指针相关联。有点让您希望使用旧的 Pascal 冒号来消除歧义 - 将共享类型与 names-with-modifiers 列表分开。
  • @Steve314 但是想想当你有typedef int *foo_t;,然后是foo_t a, b, c;时会发生什么。此时,C“考虑”* 与该类型相关联。 (尽管我认为 C 语言并没有真正“考虑”任何事情......)
【解决方案3】:

后者更明确,因为它表明您正在创建一个指向浮点的变量,而不是创建一个浮点指针的变量。这在以下结构中变得很重要:

float *foo, bar;

foo 是一个指向浮点数的指针,但 bar 只是一个浮点数。

【讨论】:

    【解决方案4】:

    主要是编码风格的问题。但是,大多数 C 程序员更喜欢使用第二个选项:float *var;,因为它更接近于语言语法绑定 * 星号的方式:* 绑定到声明符,而不是类型说明符。

    换句话说,C 程序员将float *var 翻译为*var 是浮点类型。但var 的类型不是float*

    维基百科文章C variable types and declarations有更详细的解释

    另外,你可能会发现C Pointer Syntax: Style poll这个问题很有趣。

    【讨论】:

      【解决方案5】:

      正如其他人所说,这没有区别 - 风格问题。请注意,在 C++ 中,习惯上是这样写的:

      type* var;
      

      因为指针是类型的一部分——至少对于自定义类型是这样。但是通过扩展内置类型也是如此。因此,在 C 中做同样的事情以保持一致是有道理的。就我个人而言,我发现将指针作为类型的一部分更直观。

      【讨论】:

        【解决方案6】:

        实际上没有区别;声明被解析好像它是写float (*varname);

        在 C 和 C++ 中,声明都以 表达式 为中心,而不是对象;基本上,声明的形式应该与可执行代码中的表达式形式相匹配(IOW,声明模仿使用)。例如,如果您有一个指向名为 p 的整数的指针,并且您想访问 p 指向的整数 value,您可以像这样取消引用该指针:

        x = *p;
        

        表达式*p的类型是int;因此,声明应该看起来像

        int *p;
        

        同样,如果您有一个名为 arr 的 int 数组,并且您想访问特定元素 i 处的整数值,您可以编写

        x = a[i];
        

        表达式a[i]的类型是int;因此,声明应该看起来像

        int a[N];
        

        在上面的例子中,*pa[N] 被称为声明符;声明符引入了正在声明的对象的名称以及类型说明符中未提供的其他类型信息pa 的 int 属性由类型说明符 int 提供,但 p 的指针属性和 a 的数组属性由它们各自的 声明符提供

        这是很重要的一点,也是需要强调的一点;无论空格如何,int *p;int* p;* 都绑定到 声明符,而不是类型说明符。您可以用任何一种方式编写它的事实是 C(和 C++)语法的意外,因此有一种观点认为指针变量应该声明为 T* p; 而不是 T *p;,因为 type of p 是“指向 T 的指针”。我的问题是推理 only 适用于简单的指针类型;我们不能以同样的方式对待数组或函数类型。例如,我们不能写int[N] arr;,即使arrtype 是“N-element array of int”。当我们开始声明指向数组的指针,或指向函数的指针,或它们的组合时,它真的会崩溃。例如:

        int *(*(*(*farr)())[N])();
        

        farrtype 是“指向函数的指针,该函数返回指向 N 元素数组的指针,该指针指向返回指向 int 的指针的函数”。除了“int”之外的所有东西都是声明符的一部分;写int* (*(*(*farr)())[N])(); 甚至int*(*(*(* farr)())[N])(); 只会……很傻。

        我相信坚持为指针声明写T* p;会导致更多的混乱,而不是更少。就像 Stroustrup 和大量 C++ 程序员想要假装的那样,C 和 C++ 中的声明以 表达式 为中心,而不是对象。

        由于我是编写 C++ 代码的大型团队的一员,因此我遵循商定的编码指南,其中包括将指针和引用声明为 T* p;T& r;,但这让我每次都咬牙切齿去做吧。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多