【问题标题】:how string (command line) are stored in char**argv and int *argv?字符串(命令行)如何存储在 char**argv 和 int *argv 中?
【发布时间】:2016-04-16 00:24:08
【问题描述】:

第一个 sn-p:

#include<stdio.h>
int main(int argc, char **argv)
{
int i;
for(i=1; i<argc; i++)
    printf("%s\n", argv[i]);
return 0;
}

加载时间输入:

./a.out devang samir

输出:

德旺
萨米尔

第二次sn-p:

#include<stdio.h>
int main(int argc, int *argv)
{
int i;
for(i=1; i<argc; i++)
    printf("%s\n", argv[i]);
return 0;
}

加载时间输入:

./a.out devang samir

输出:

德旺
萨米尔

在这两种情况下,我的输出都是一样的,但是为什么?

  • 在第一种情况下,字符串(命令行)如何存储在 char** argv 中?
  • 在第二种情况下,字符串(命令行)如何存储在 int * argv...中?

【问题讨论】:

  • 第二个程序展示了Undefined Behaviour。任何事情都可能发生(甚至像一个正确的程序一样工作)。
  • 这被称为 undefined 行为是有原因的。你有什么理由不只是使用正确的版本,而是射你的脚?
  • 那是什么原因? @Olaf
  • 虽然我的问题比较修辞,但我不明白你的问题是什么。
  • @Olaf OP 当然应该得到警告。我同意,试图弄清楚为什么未定义的行为有时会达到预期目的并不是一个特别好的利用时间,但这似乎是 OP 帖子的唯一目的。

标签: c pointers command-line-arguments main


【解决方案1】:

C11 标准将第 5.1.2.2.1 章中main() 的函数签名指定为

程序启动时调用的函数名为main。实现声明没有 这个函数的原型。它应使用int 的返回类型定义,并且没有 参数:

int main(void) { /* ... */ }

或带有两个参数(此处称为argcargv,尽管可以是任何名称 使用,因为它们在声明它们的函数中是本地的):

int main(int argc, char *argv[]) { /* ... */ }

或等效的;[...]

关于约束,

如果argc的值大于零,则数组成员argv[0]通过 argv[argc-1] inclusive 应包含指向字符串的指针,[...]

那么,在你的第二种情况下,

 int main(int argc, int *argv)

char*int(通常是 argv[n])是完全不同的类型(即不兼容的类型),您的第二个程序调用 undefined behavior

具体来说,在没有原型的函数的情况下,调用时传递给函数的参数应该完全匹配预期参数的类型。

引用标准,第 §6.5.2.2 章

[...] 如果函数是用不包含原型的类型定义的,那么 提升后的参数与之后的参数不兼容 促销,行为未定义。

【讨论】:

  • 你的意思是char *int,而不是charint
  • @TomKarzes 对不起,我没有得到你。能详细说明一下吗?
  • OP 使用int 代替char *,而不是char。正确类型:char ** 错误类型:int *。不同之处在于正确类型的char * 被错误类型的int 替换。这就是它“起作用”的原因:intchar * 在 OP 的机器上显然具有相同的大小。 intchar 没有。
  • @TomKarzes 这看起来更好吗?
猜你喜欢
  • 1970-01-01
  • 2020-11-03
  • 2013-09-08
  • 2011-07-08
  • 2020-05-19
  • 1970-01-01
  • 1970-01-01
  • 2022-01-06
  • 2011-07-08
相关资源
最近更新 更多