【问题标题】:`int main(i){ printf("i = %d\n", i); }` i value is 1. why ? please explain?`int main(i){ printf("i = %d\n", i); }` 我的值为 1。为什么?请解释?
【发布时间】:2019-10-18 20:03:36
【问题描述】:

为什么它打印 I value as 1,有人可以解释一下吗?

#include<stdio.h>
int main(i)
{ 
    printf("i = %d\n", i); 
}

输出 i = 1。

【问题讨论】:

  • 你还没有初始化i,所以它会打印一个随机(未定义)的值。
  • main 函数的第一个参数是 argc,因此您的 i 会从命令行显示“传递了一个参数”。当应用程序运行时,第一个参数是包含main 函数的可执行文件的路径:stackoverflow.com/q/3024197/6352710。如果您声明第二个参数,您将能够打印路径。
  • 它根本不是未定义的: main 将传递命令行参数的数量和它们的列表。第一个参数是命令名称本身,因此 argv(或在本例中为 i)将为 1。

标签: c initialization implicit


【解决方案1】:

Ci 解释为类型 int - if you don't declare a variable, its default type is int。巧合的是,main 习惯于被称为int main(int argc, char **argv),因此您的i(现在是int)适合第一个参数。 main 将允许您只使用一个参数调用它,but this is technically undefined behavior - 不要这样做。

第一个值argc 是一个数字,详细说明了给出了多少命令行参数。 (第二个是这些参数的字符串。)在您的情况下,只给出了一个命令行参数,即可执行文件的名称(可能是./a.out)。

尝试使用 ./a.out some strings here 运行您的代码 - 您会注意到打印的值不同。

【讨论】:

  • 我认为隐式类型与通常调用main() 的方式没有任何关系。这是一个旧式函数定义,其中未在参数列表中指定类型。而未声明变量的默认类型是int
  • @Barmar 我不知道,我认为它正在转换它 - 我会寻找该行为的参考并将其链接到问题中。
【解决方案2】:

这里有两三个不同的小奥秘。不知道你想知道哪一个,所以我想我会回答所有三个。

  • 您是如何在没有 i 类型的情况下声明 int main(i) 的?

  • 您是如何将main 声明为接受一个参数而不是传统的两个参数的?

  • 运行时值 1 是从哪里来的?

答案:

(1) 很久以前,在相当长的一段时间以前,在 C 语言的黎明(或至少是早晨),函数定义语法是不同的。你没说

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

相反,你说

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

那时“隐式int”也风靡一时。所以如果你只是写了

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

编译器说“好的,有一个参数argv,它是一个char **,还有一个参数argc,它是一个......哦,你没有说,所以我只是静静地假设int。”

由于 C 在向后兼容性方面一直非常重视,许多编译器今天仍然接受旧语法,即使它已经正式过时了一段时间。

(2) 另外,在您的情况下,您完全放弃了 argv 部分。 main 应该有两个参数,这是程序启动时系统调用它的方式,但你只声明它接受一个。那么为什么它会起作用呢?

严格来说,当使用与预期数量不同的参数调用函数时,行为是未定义的,但这是您经常可以避免的事情,尤其是在传递的参数多于预期的情况下。因此,尽管系统传递了您的程序没有预料到的第二个 argv 参数,但额外的参数只是被悄悄地丢弃了。

(3) 那么,1 是从哪里来的呢?嗯,这是因为main 的传统argcargv 参数的实际含义。 C 的main 定义基于命令行调用。通常人们会输入类似的东西

programname somefilename someotherargument

然后按回车键。这会调用一个名为programname 的程序,它带有两个命令行参数somefilenamesomeotherargument。那么这些是如何传递给main的呢?

嗯,argc 是对其中有多少个的计数,argv 是参数字符串本身的数组(v 代表“向量”)。并且参数列表始终包含程序名称本身。所以如果你调用

programname somefilename someotherargument

然后argc 以 3 的形式出现,argv 以数组的形式出现

{ "programname", "somefilename", "someotherargument", NULL }

但是如果你调用不带参数的东西,那么argc 仍然是 1。所以这就是你看到的 1 的来源。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-15
    • 2020-12-28
    • 2012-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多