尝试创建有关 Collatz 猜想的程序时出现奇怪的错误。如何解决?
strange errors while trying to create a program about Collatz conjecture. How to solve them?
我正在写这个程序:
“程序从命令提示符中获取一个数字,它 returns 冰雹序列的长度”。
冰雹序列定义如下:
- 如果是偶数,则减半(n / 2)。
- 如果数字是奇数,则将数字乘以三倍,然后加一
(3 * n + 1).
如果序列到达1,则算法停止。
我是这样写代码的(注意每个数字的末尾必须有一个逗号,逗号后有一个space,所以我就这样打印了):
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
if (argc != 2) {
return -1;
}
if (argv[1] <= 0) {
return 0;
}
int n = strtod(argv[1], NULL);
int length = 0;
while (n == 1) {
if (n % 2 == 0) {
n /= 2;
printf("%d%s", n, ",");
++length;
printf("%s", " ");
}
else {
n = (3 * n) + 1;
printf("%d%s", n, ",");
++length;
printf("%s", " ");
}
}
return length;
}
我有两个错误:
- 在使用 strtod 函数时,调试器警告我“从 double 到 int 的转换:可能丢失数据”。为什么? argv 不包含双精度,但它是一个字符串。 strtod 在字符串和十进制之间进行转换;我错了吗?
- 我在终端输入“hailstone 3”。但终端无法识别该命令。所以我只输入了3,但是终端returns 3,没有任何计算。
编辑:我已经这样编辑了我的代码:int main(int argc, char* argv[]) {
int n = strtol(argv[1], NULL, 10);
if (n <= 0) {
return 0;
}
所以,基本上,我使用了 strtol 函数,然后我放置了 if 语句,因为我使用变量 (n) 而不是使用字符串(我认为它更容易) .但是什么都没有改变。 (我仍然有命令行问题,但我不再有警告)。
strtod
用于转换十进制值,警告告诉你将值转换为double
,并将其分配给int
会导致小数部分丢失分配值的一部分,在这种情况下不会产生任何结果,但无论如何您应该使用 strtol
代替。
在您的代码中,由于 argv[1]
是一个字符串并且您将其与 int
值 0
进行比较,比较不正确,请使用上述 strtol
,或将其与字符串进行比较,例如 const char* str = "0"
与 strcmp
(argv[1], str)
之类的东西,尽管我更喜欢第一种方法。
至于程序启动,请尝试./hailstone 3
,假设您在编译源代码时将可执行文件提供给您的程序。
例如,假设您的编译器是 gcc,您必须使用类似 gcc -o hailstone source.c
的东西,其中 source.c
是源代码文件的名称。
使用Visual Studio IDE,构建结果不会在项目根目录下,您需要导航到文件所在的文件夹。
我正在写这个程序: “程序从命令提示符中获取一个数字,它 returns 冰雹序列的长度”。 冰雹序列定义如下:
- 如果是偶数,则减半(n / 2)。
- 如果数字是奇数,则将数字乘以三倍,然后加一 (3 * n + 1).
如果序列到达1,则算法停止。
我是这样写代码的(注意每个数字的末尾必须有一个逗号,逗号后有一个space,所以我就这样打印了):
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char* argv[]) {
if (argc != 2) {
return -1;
}
if (argv[1] <= 0) {
return 0;
}
int n = strtod(argv[1], NULL);
int length = 0;
while (n == 1) {
if (n % 2 == 0) {
n /= 2;
printf("%d%s", n, ",");
++length;
printf("%s", " ");
}
else {
n = (3 * n) + 1;
printf("%d%s", n, ",");
++length;
printf("%s", " ");
}
}
return length;
}
我有两个错误:
- 在使用 strtod 函数时,调试器警告我“从 double 到 int 的转换:可能丢失数据”。为什么? argv 不包含双精度,但它是一个字符串。 strtod 在字符串和十进制之间进行转换;我错了吗?
- 我在终端输入“hailstone 3”。但终端无法识别该命令。所以我只输入了3,但是终端returns 3,没有任何计算。
编辑:我已经这样编辑了我的代码:int main(int argc, char* argv[]) {
int n = strtol(argv[1], NULL, 10);
if (n <= 0) {
return 0;
}
所以,基本上,我使用了 strtol 函数,然后我放置了 if 语句,因为我使用变量 (n) 而不是使用字符串(我认为它更容易) .但是什么都没有改变。 (我仍然有命令行问题,但我不再有警告)。
strtod
用于转换十进制值,警告告诉你将值转换为double
,并将其分配给int
会导致小数部分丢失分配值的一部分,在这种情况下不会产生任何结果,但无论如何您应该使用 strtol
代替。
在您的代码中,由于 argv[1]
是一个字符串并且您将其与 int
值 0
进行比较,比较不正确,请使用上述 strtol
,或将其与字符串进行比较,例如 const char* str = "0"
与 strcmp
(argv[1], str)
之类的东西,尽管我更喜欢第一种方法。
至于程序启动,请尝试./hailstone 3
,假设您在编译源代码时将可执行文件提供给您的程序。
例如,假设您的编译器是 gcc,您必须使用类似 gcc -o hailstone source.c
的东西,其中 source.c
是源代码文件的名称。
使用Visual Studio IDE,构建结果不会在项目根目录下,您需要导航到文件所在的文件夹。