char** v *char[] 在 C 语言中

char** v *char[] in C

提问人:R-Rothrock 提问时间:10/26/2023 最后编辑:Vlad from MoscowR-Rothrock 更新时间:10/28/2023 访问量:95

问:

当我通读 C 代码时,我经常看到这样:

int main(int argc, char **argv)

但我总是学会这样做:

int main(int argc, char *argv[])

那么,我为什么要使用一个而不是另一个呢?我知道它们在技术上是不同的,但我不明白为什么我会使用一个而不是另一个。

提前致谢。

C 指针 参数 函数声明

评论

0赞 Craig Estey 10/26/2023
你到底是从哪里学来的?一直都是.哎呀,ISO/C [c11] 又来了!由于 的最终来源来自内核将数据填充到用户空间并推送指针,似乎更合适。但是,即使有 ,你仍然可以做,它的工作方式就像 [所以有点有争议的问题]。但是,我在 1981 年编写了我的第一个 C 程序,从那时起我就一直在使用。并且,内核将传递:char *argv[]char **argvargvchar **argvchar *argv[]++argvchar **argvchar **argvint argc,char **argv,char **environ
2赞 ikegami 10/26/2023
@Craig埃斯蒂,什么?意识到它们与参数是 100% 等效的。所以这个谈话总是一个,并且内核传递了一个版本?这是无稽之谈。
3赞 n. m. could be an AI 10/26/2023
它们在技术上完全相同。在这两种情况下,类型都是。选择其中之一是个人审美偏好的问题。argvchar**
0赞 John Bollinger 10/26/2023
@CraigEstey,他们可能是从 K&R 1ed 那里得到的,K&R 1ed 在其示例中使用第二个参数的形式。这几乎永远等同于(作为函数参数),而且绝对在 ANSI C 和每个版本的 ISO C 中。char *argv[]mainchar **argv
0赞 R-Rothrock 10/26/2023
@CraigEstey老实说,我不知道我从哪里学来的。我没有使用任何特定的课程来学习 C,所以没有确定的方法可以知道。

答:

3赞 Seva Alekseyev 10/26/2023 #1

从功能上讲,为了访问参数,这两种表示法是等价的。

表示法可能具有区分指向单个元素的指针和指向数组的指针的边际优势;可以误读为 类型的 out参数。[]char**char*

不过不太可能。main()argv

评论

1赞 R-Rothrock 10/26/2023
所以这只是一种偏好。感谢您的帮助。
2赞 Vlad from Moscow 10/26/2023 #2

来自 C 标准(6.7.6.3 函数声明符(包括原型)):

7 应调整参数为“类型数组”的声明 到“限定的指向类型的指针”,其中类型限定符(如果有) 是在数组类型派生的 [ 和 ] 中指定的那些。 如果关键字 static 也出现在数组的 [ 和 ] 中 类型派生,然后对于对函数的每次调用,值 相应的实际参数应提供对第一个 元素,其元素的元素至少与 size 表达式指定的元素数相同。

所以这些声明:main

int main(int argc, char **argv)

int main(int argc, char *argv[])

是等价的。如果要排除,则只能声明一次,您可以声明两次相同的函数,例如:main

void f( char * [] );

和:

void f( char ** );

在同一个翻译单位。此外,您甚至可以声明上述函数,例如

void f( char * [10] );

void f( char * [100] );

因为在任何情况下,具有数组类型的参数都会被编译器调整为指向元素类型的指针,例如

void f( char **  );

对于具有函数类型的参数,也使用相同的方法。

例如,这两个函数声明:

void f( void ( void ) );

和:

void f( void ( * )( void ) );

是等效的,因为具有函数类型的函数参数由编译器调整为指向函数类型的指针类型。

从 C 标准:

8 将参数声明为“函数返回类型”应为 调整为“指向函数返回类型的指针”,如 6.3.2.1 所示。