【问题标题】:typedef and variable namestypedef 和变量名
【发布时间】:2018-01-05 02:44:33
【问题描述】:

忽略我为什么要这样做,只是想了解这里发生了什么: 此代码编译:

#include <stdio.h>
typedef char byte;

int main (void) 
{
    byte var_byte;
    int byte = 10;

    printf("\n Test program: %d\n", byte);
}  

但是,如果我更改变量声明的顺序,它就不会编译。

这不会编译:

#include <stdio.h>
typedef char byte;

int main (void)
{
    int byte = 10;
    byte var_byte;

    printf("\n Test program: %d\n", byte);
}

编译器错误:

b.c:7:8: error: expected ‘;’ before ‘var_byte’
   byte var_byte;
        ^~~~~~~~

有人能解释一下为什么顺序很重要吗?

【问题讨论】:

  • 不编译出现什么错误?
  • 而在第二个中,你创建一个与类型同名的变量,然后尝试使用它下面的类型。您可能正在使用变量名隐藏 typedef。
  • 您可能会注意到:int main (void) { typedef char byte; byte var_byte; int byte = 10; printf("\n Test program: %d\n", byte); } 无法编译,因为类型名称 byte 不能在 main() 的范围内更改 - 它只能在内部范围内更改。
  • 已经多次声明,将相同的名称用于变量名称的 typedef 名称是非常糟糕的编程习惯。通常,编译器可以区分差异,但并非总是如此。 OP 找到了“并非总是”实例之一

标签: c variables scope declaration typedef


【解决方案1】:

在这个节目中

#include <stdio.h>
typedef char byte;

int main (void)
{
    int byte = 10;
    byte var_byte;

    printf("\n Test program: %d\n", byte);
}

变量名byte隐藏了typedef的名称。

来自 C 标准(6.2.1 标识符范围)

  1. ... 如果标识符在同一名称空间中指定两个不同的实体,则范围可能会重叠。如果是这样,一个实体的范围 (内部范围)将严格在另一个范围之前结束 实体(外部范围)。 在内部范围内,标识符 指定在内部范围内声明的实体;声明的实体 在外部范围内隐藏(不可见)在内部 范围。

注意一个标识符的名字和一个typedef名字属于同一个名字空间。

typedef 名称在全局范围(文件范围)中声明,而变量名称在内部块范围中声明,变量名称隐藏在全局范围中声明的名称。

考虑这个程序。

#include <stdio.h>
typedef char byte;

void f( void );

int main (void)
{
    int byte = 10;

    printf("\n Test program: %d\n", byte);

    f();
}

void f( void )
{
    byte c = 'A';
    printf( "%c\n", c );
}

在函数main的块范围内(相对于文件范围的内部范围),typedef的名称被同名变量的声明隐藏。

但是在函数f 的块范围内,在 typedef 中声明的名称是可见的,因为函数的块范围内的其他声明都不会隐藏在 typedef 中声明的名称。

这是一个更有趣的程序,它处理声明点(它是一个 C++ 术语)

#include <stdio.h>

size_t byte = 255;

int main(void) 
{
    typedef int byte[byte];

    {
        byte byte;

        printf( "sizeof( byte ) = %zu\n", sizeof( byte ) );
    }

    return 0;
}

它的输出可能看起来像

sizeof( byte ) = 1020

这里是在文件范围内有一个名为byte的声明变量

size_t byte = 255;

在函数main的外部块作用域中引入了typedef namebyte

typedef int byte[byte];

它在声明符声明后隐藏了先前声明的名称byte。就是在这个typedef中

    typedef int byte[byte];

方括号中的名称byte 对应于全局名称byte

然后在内部块作用域中声明一个具有相同名称的数组 byte 隐藏 typedef 名称。

byte byte;

注意表达式中的那个

sizeof( byte )

这里使用了数组的名称而不是 typedef 名称。

【讨论】:

    【解决方案2】:

    在此处编辑:(对问题的误解)

    当您在 C 中声明变量时,它不会查找 typedef 结构来查看是否与变量命名相同的结构。在第一个代码上,

    byte var_byte; 
    

    这行代码出现在变量int byte 的声明之前。计算机将查找单词字节的最新引用,因为它是此处的结构名称。

    在第二个中,变量int byte 不会返回错误,因为您仍然可以在 C 中创建具有相同结构类型名称的变量。但是在您这样做之后,您无法为该结构创建新结构,因为计算机会认为它指的是变量名而不是结构类型,因为变量是最近声明的

    【讨论】:

    • 这并没有(至少没有清楚地)解释为什么顺序很重要。
    • @Schwifty McSchwifulface 现在怎么样了?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-23
    • 1970-01-01
    • 2012-11-02
    • 1970-01-01
    • 2021-03-22
    • 2021-04-05
    • 1970-01-01
    相关资源
    最近更新 更多