char和char之间的区别[1]

时间:2010-11-08 01:20:33

标签: c++ arrays char static-array

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

的示例:

struct SomeStruct
{
   char x;
   char y[1];
};

对于unsigned char,请遵循相同的原因吗?

3 个答案:

答案 0 :(得分:39)

主要区别在于您用来访问一个字符的语法。

“访问”是指使用语言中的各种运算符对其进行操作,与char数组相比,应用于char时,大多数或所有运算符都会执行不同的操作。这使得听起来好像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

y无法转让这一事实并不能阻止SomeStruct被转让:

b = a; // OK

所有这些都与类型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

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

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

答案 1 :(得分:11)

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

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

答案 2 :(得分:3)

除了Steve强调的使用中的符号差异外,char [1]可以传递给例如template <int N> void f(char(&a)[N]),其中char x = '\0'; f(&x);不匹配。可靠地捕获数组参数的大小非常方便且令人放心。

它也可能意味着不同的东西:要么实际长度可能更长(由dmckee解释),要么内容在逻辑上是ASCIIZ字符串(在这种情况下恰好是空的),或者字符数组(恰好有一个元素)。如果结构是几个相关结构之一(例如,数组向量,其中数组大小是模板参数,或者是某些I / O操作所需的内存布局的编码),则完全可能与其他字段有某些相似性数组可能更大的地方会建议偏好单字符数组,从而使支持代码更简单和/或更普遍适用。