c++ - char argv[][7] 和 char *argv[] 的区别

标签 c++ c

<分区>

最近在学习C语言。我读到有一些方法可以创建字符串数组。 char argv[][7]char *argv[] 有区别吗?如果没有你更喜欢用什么?

最佳答案

引用自 C99 标准 §6.2.5 ¶20(类型)

An array type describes a contiguously allocated nonempty set of objects with a particular member object type, called the element type. Array types are characterized by their element type and by the number of elements in the array.

该标准在 §6.2.5 ¶22 中进一步说明

An array type of unknown size is an incomplete type. It is completed, for an identifier of that type, by specifying the size in a later declaration (with internal or external linkage).

数组下标运算符[] 的优先级高于* 运算符。因此,声明

char *argv[];

argv 定义为指向未知大小字符的指针数组,因为未指定数组大小。数组 argv 是不完整的类型。这是假设上述语句中的表达式不作为函数参数出现。由于数组 argv 是不完整类型,您必须在使用前提供其大小信息。这意味着您应该将上述语句作为声明并在其他地方提供其定义,以便链接器解析它。阅读本文以了解声明和定义之间的区别 -

What is the difference between a definition and a declaration?

// array declaration.
// this does not allocate space
// but only provides type information
// though of an incomplete type.
// argv must have internal or external linkage. 
extern char *argv[];

// definition of the array.
// complete information and
// allocates memory for it.
// in the same translation unit or 
// a different one.
char *argv[8];

您还可以使用数组初始化列表来初始化数组,数组的大小将从列表中推断出来。

// size of the array argv is determined
// explicitly to be 2
char *argv[] = {"Hello", "World"};

// the above is equivalent to
char *argv[2];
argv[0] = "Hello";
argv[1] = "World";

注意:以上只是为了演示数组的初始化,并没有明确提到它的大小。字符串字面值是只读的,所以语句最好写成

const char *argv[] = {"Hello", "World"};

但是,如果它作为函数参数出现,则它等同于 char **argv

int main(int argc; char *argv[]);
// equivalent to
int main(int argc, char **argv);

下面语句中的数组也是如此。

char argv[][7];

上述语句将 argv 定义为 char[7] 类型元素的数组,即 7 个字符的数组。同样,未指定数组 argv 的大小。因此,argv 是一个不完整的类型。假设它不作为函数参数出现,则该语句应该做成声明,因为它是一个不完整的类型,它的定义应该在别处提供。

// array declaration.
// argv must have internal or external linkage
extern char argv[][7];

// definition.
// in the same translation unit
// or a different one
char argv[10][7];

数组可以像前一种情况一样被初始化,并且大小将从初始化列表中隐式确定。

// size of the array argv is inferred from 
// the initializer list to be 3.
char argv[][7] = {{'a', 'b', 'c', 'd', 'e', 'f', 'g'},
                  {'a', 'b', 'c', 'd', 'e', 'f', 'g'},
                  {'a', 'b', 'c', 'd', 'e', 'f', 'g'}};

但是,如果数组表达式作为函数参数出现,那么它就等同于
char(*)[7],即指向数组的指针7 个字符。

void foo(char argv[][7]);
// equivalent to
void foo(char (*)[7])

这是因为您不能将数组传递给函数。实际传递的是指向数组第一个元素的指针。因此,函数中的数组参数被隐式转换为指向数组元素的指针类型。请阅读此以获取更多详细信息 -

Why do C and C++ compilers allow array lengths in function signatures when they're never enforced?

关于c++ - char argv[][7] 和 char *argv[] 的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23197806/

相关文章:

c++ - Boost::测试和模拟框架

c++ - 单击 QPushButton 时,将数据从 QLineEdit 转换为 QString。

c - 为什么我的程序使用线程抛出 14000000 而不是 10000000 ?

c - 我如何使用 C 语言中的 stdarg 编写该代码

c++ - 如何查询二进制文件的源代码版本

C++ 多重继承 - 为什么你没有工作?

c++ - 中断 parallel_for_each 的子任务

c++ - C++ 中附加的 char* 的奇怪输出

c - 带有种子的随机数生成器

c - 多线程-如果满足条件如何停止所有线程?