-4

long long我有一个接受参数的 c 程序。当我尝试将这个 long 转换为它的二进制表示时,结果证明都是错误的。但是如果我设置一个long long等于参数值的long long变量,那么我得到正确的二进制表示。

  int main(int argv, long long value)
{
        long long i = value; // value = 2
        long long e = 2;
        printBits(sizeof(e), &e); // 0000000000000000000000000000000000000000000000000000000000000010
        printBits(sizeof(i), &i); // 0000000000000000011111111111110000010000111010101110101000001000
        return 0;
}

因此,您可以在上面看到通过控制台检索到的参数,因为输入与应有的值相差甚远。

printBits() 是此解决方案的复制粘贴。

有人可以澄清发生了什么吗?

4

2 回答 2

3

主要的签名是

int main(int argc, char** argv)

不幸的是,C 编译器可能非常宽容,因此可能发生的情况是您的指针char*被默默地强制转换为long long,从而导致胡说八道。

您需要实际解析参数,例如使用strtoll.

在没有编译器标志的情况下使用 C-Wall是自找麻烦。启用所有警告后,您会立即发现问题:

warning: second argument of ‘main’ should be ‘char **’ [-Wmain]
int main (int argc, long long value)
    ^~~~
于 2017-09-15T12:57:17.423 回答
0

main()代码中的签名

 int main(int argv, long long value)

对于托管环境是无效和错误的。第二个参数应该是 type char **。通过将argc等价定义为 as long long,您试图将类型接收char **long long类型中,这会导致未定义的行为,因为它们无论如何都是不兼容的类型。

换句话说,提供的命令行参数作为指向字符串的指针传递。您需要应用适当的转换以将它们恢复为long long或任何其他兼容类型。strtoll()就是为此目的而制作的。

引用C11,第 §5.1.2.2.1 章,

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

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

或带有两个参数(这里称为argcand argv,尽管可以使用任何名称,因为它们对于声明它们的函数是本地的):

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

或等价物;10) 或以其他一些实现定义的方式。

第 2 段,

— 如果 的值argc大于零,则argv[0]通过 argv[argc-1]inclusive 的数组成员应包含指向字符串的指针,这些指针在程序启动之前由宿主环境赋予实现定义的值。目的是从托管环境中的其他地方向程序提供在程序启动之前确定的信息。如果主机环境不能提供大写和小写字母的字符串,则实现应确保以小写形式接收字符串。

— 如果 的值argc大于零,则 argv[0] 指向的字符串代表程序名;argv[0][0]如果主机环境中没有程序名,则应为空字符。如果 的值argc大于 1,则argv[1]through指向的字符串argv[argc-1] 表示程序参数。

于 2017-09-15T12:54:41.847 回答