我有一个接受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.
的复制粘贴有人可以清楚发生了什么吗?
答案 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) { /* ... */ }
或有两个参数(此处称为
argc
和argv
,但可能有任何名称 使用,因为它们是声明它们的函数的本地函数):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]
指向的字符串 代表程序参数。