char和char之间的区别[1]

55 c++ arrays char static-array

在C++中,使用char和char [1]之间有什么区别(如果有的话).

例子:

struct SomeStruct
{
   char x;
   char y[1];
};
Run Code Online (Sandbox Code Playgroud)

对于unsigned char,原因如下吗?

Ste*_*sop 39

主要区别仅在于您用于访问一个char的语法.

通过"访问"我的意思是,使用语言中的各种运算符对其进行操作,当应用于charchar数组进行比较时,大多数或所有运算符都执行不同的操作.这使得它听起来好像xy几乎完全不同.如果事实上它们都"由"一个字符组成,但该字符以非常不同的方式表示.

实现可能会导致其他差异,例如,它可能根据您使用的不同而对齐和填充结构.但我怀疑它会.

运算符差异的一个示例是char是可分配的,而数组不是:

SomeStruct a;
a.x = 'a';
a.y[0] = 'a';
SomeStruct b;
b.x = a.x; // OK
b.y = a.y; // not OK
b.y[0] = a.y[0]; // OK
Run Code Online (Sandbox Code Playgroud)

但是y不可分配的事实不会停止SomeStruct分配:

b = a; // OK
Run Code Online (Sandbox Code Playgroud)

所有这些都与类型无关char.类型的对象和大小为1的那种类型的数组在内存中几乎是相同的.

顺便说一句,有在它使一个很大的区别,你"用"出来的背景charchar[1],并且有时帮助迷惑人到思维,数组是真正的指针.不是你的例子,而是作为一个函数参数:

void foo(char c);     // a function which takes a char as a parameter
void bar(char c[1]);  // a function which takes a char* as a parameter
void baz(char c[12]); // also a function which takes a char* as a parameter
Run Code Online (Sandbox Code Playgroud)

C++语言的声明中提供的数字barbaz完全被忽略的数字.显然有人在某种程度上认为程序员作为一种文档形式会很有用,这表明该函数baz期望其指针参数指向12个字符数组的第一个元素.

在bar和baz中,c从来没有数组类型 - 它看起来像一个数组类型,但它不是,它只是一个奇特的特殊情况语法,具有相同的含义char *c.这就是为什么我把引号放在"使用"上 - 你根本就没有使用char[1]它,它只是看起来像它.

  • +1,我厌倦了所有答案,说'y`是一个指针. (9认同)
  • 很好,明确的答案.另一个不同的是使用构造函数进行初始化(如果他要添加一个),这在当前C++中使用数组时可能无法工作(除了对它们进行值初始化). (4认同)
  • 主要区别实际上只是类型系统分配的*类型*.`x`的类型为`char`,而`y`的类型为`char [1]`.我知道这听起来像我只是陈述显而易见的,但这确实是主要区别.例如,您不能将`y`传递给期望`char`作为参数的函数.但是最终x和y在传递给`sizeof`运算符时都会返回相同的值,并且两者都可能在内存中以完全相同的方式表示.此外,`y`可以降级为指针,这意味着你可以将它传递给类似`strcpy`的东西,但你不能用`x`做到这一点. (3认同)
  • @ J-16:char指针(在你的机器上)的大小是多少?你的大小是多少?`char*p; char a [1]; assert(sizeof(p)== sizeof(a));`will*fail;*这都是关于type的,不是关于lvalue或rvalue. (2认同)

dmc*_*kee 11

如果你实际上已经将构造char y[1]视为生产代码中结构的最后一个成员,那么很可能你遇到了struct hack的一个实例.

这个短阵列是一个真实但可变长度阵列的替身(回想一下,在c99之前,c标准中​​没有这样的东西).程序员总是会在堆上分配这样的结构,注意确保分配足够大,以满足他想要使用的数组的实际大小.

  • @Billy:我认为@ Steve的建议仍适用于那种情况,但原因不同.每当你必须使用Win32 API时,请担心......;) (4认同)