C:作为二进制的命令行参数与作为二进制的局部变量不同

时间:2017-09-15 12:52:56

标签: c binary command-line-arguments long-long

我有一个接受long long参数的程序。当我尝试将此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()是来自此solution.

的复制粘贴

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

2 个答案:

答案 0 :(得分:3)

main的签名是

int main(int argc, char** argv)

不幸的是,C编译器非常宽松,所以可能发生的事情是你的char*指针被静默地转换为long long,导致无意义。

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

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

warning: second argument of ‘main’ should be ‘char **’ [-Wmain]
int main (int argc, long long value)
    ^~~~

答案 1 :(得分:0)

代码中main()的签名

 int main(int argv, long long value)

对于托管环境无效且错误。第二个参数应该是char **类型。通过将argc等效项定义为long long,您尝试将char **类型接收到long long类型,这会导致undefined behavior,因为它们不是无论如何,兼容的类型。

换句话说,提供的命令行参数作为指向字符串的指针传递。您需要应用正确的转换才能将其恢复为long long或任何其他兼容类型。 strtoll() 就是出于此目的。

引用C11,章节§5.1.2.2.1,

  

程序启动时调用的函数名为main。实施宣布否   这个功能的原型。它应定义为返回类型int且没有   参数:

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

或有两个参数(此处称为argcargv,但可能有任何名称   使用,因为它们是声明它们的函数的本地函数):

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

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

和第2段,

  

- 如果argc的值大于零,则数组成员argv[0]通过   argv[argc-1]包含应包含指向字符串的指针   程序启动前主机环境实现定义的值。该   意图是在程序启动之前为程序提供信息   来自托管环境中的其他地方。如果主机环境不具备   为字符串提供大写和小写的字母,实现   应确保以小写字母收到字符串。

     

- 如果argc的值大于零,则argv [0]指向的字符串   代表程序名称; argv[0][0]如果是,则为空字符   程序名称不能从主机环境中获得。如果argc的值是   大于一,argv[1]通过argv[argc-1]指向的字符串   代表程序参数。