【问题标题】:Why there is a difference in output of argc?为什么argc的输出有差异?
【发布时间】:2017-07-14 11:12:13
【问题描述】:

为什么下面的argc的输出会有差异?

第一:

#include<stdlib.h>
#include<stdio.h>
#include<iostream>
int main(int argc,char *argv[])
{
  for(int i=1;i<=argc;i++)
    std::cout<<argv[i]<<"\n"<<std::endl;
  std::cout<<argc<<std::endl;
  return 0;
}

我得到了 argv 的输出,但是我没有得到 argc 的输出。

第二种情况:

#include<stdlib.h>
#include<stdio.h>
#include<iostream>
int main(int argc,char *argv[])
{
  std::cout<<argc<<std::endl;
  for(int i=1;i<=argc;i++)
    std::cout<<argv[i]<<"\n"<<std::endl;
  return 0;
}

我得到了 argv 和 argc 的输出。

在这两种情况下,如果我使用“printf”而不是“cout”,我都会得到 argc 的输出。

为什么argc的输出会有差异?

【问题讨论】:

  • i&lt;=argc 导致未定义的行为。如果argc 为2,则有效的argv 索引为argv[0]argv[1]argv[2] 是未定义的行为。
  • 碰巧std::cout 机制会混淆,因为您在代码中访问argv[argc]。如果您在std::cout&lt;&lt;argc&lt;&lt;std::endl; 之前运行fprintf(stdout, "%d\n", argc);,也许您可​​以获得argc 的值(就像我一样)。无论如何:总是&lt; argc,就像其他人告诉你的那样。

标签: c++ linux g++


【解决方案1】:

您的代码在这两种情况下的行为都是未定义。您需要将i&lt;=argc 替换为i &lt; argc

根据 C++ 标准,argv[argc]nullptr不要尝试取消引用。

【讨论】:

    【解决方案2】:

    C++ 规范和 POSIX 都指定 argv[argc] 将始终为空指针。当您在循环条件中使用 &lt;= 时,您尝试取消引用该空指针。

    当您取消引用空指针时,您将拥有undefined behavior (or UB)。它通常会导致崩溃printf 函数通常会检查空指针字符串并打印 "(null)",但它仍然是 UB。

    【讨论】:

    • 在第一种情况下,我在“for循环”之外使用了“cout for argc”。循环没有 {},因此只考虑下面的一个语句。它非常适合“printf”
    • @varun 更新了我的答案。
    猜你喜欢
    • 2021-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-14
    • 2015-06-04
    • 1970-01-01
    • 2021-06-11
    • 1970-01-01
    相关资源
    最近更新 更多