为什么printf("the value of str is \"%llu\"\n", str[0]);
不返回数组str中第一个数字的值?
当我尝试其他索引值(1,2,3)时,会返回预期值吗?
提供任何帮助。刚开始学习c。
#include <stdio.h>
int main()
{
// a will hold the number
unsigned long long int a=548763,i=0;
// str will hold the result which is the array
unsigned long long int str[20]= {};
// first we need to see the length of the number a
unsigned long long int b=a;
while(b>=10)
{
b=b/10;
i++;
}
// the length of the number a will be stored in variable i
// the while loop below will store the digit from the end of str to the
// the beginning
while(i>0)
{
str[i]=a%10;
a=a/10;
i--;
}
// only for test
printf("the value of str is \"%llu\"\n", str[0]); //[0]
return 0;
}
答案 0 :(得分:3)
你忘了处理最后(最不重要)的数字:
while(i>0)
{
str[i]=a%10;
a=a/10;
i--;
}
str[i] = a; // <---- last digit (here i == 0 and a < 10)
答案 1 :(得分:3)
while(i>0)
{
str[i]=a%10;
a=a/10;
i--;
}
此循环不会一直计数到0,它会倒计时到1.如果i
从不为0,则永远不会设置str[i]
。
我怀疑发生了什么是你写的while(i>=0)
并且编译器告诉你,因为i
因为无符号而永远不会是负面的,因此无法工作。这就是发生在我身上的事。奇怪的是迭代器是无符号的,可能是因为i
实际上是数字的位数,但也没有真正的理由让它无符号。 i
永远不会超过20,可能是short
。
最小的修复方法是将i
存储为有符号整数并切换到while(i>=0)
。
我会更进一步并建议:
num_digits
。i
只是迭代器以避免混淆。 i
通常用作循环迭代器,将其用于其他任何事情或将其值保留在下一个循环中是一个坏习惯。如果你必须这样做,请将其命名为其他内容。
这也意味着在填充str
的过程中会破坏位数,而无法打印所有str
。因此,请将其单独存储在num_digits
中,并根据需要将其复制到i
。
for
循环。对于简单的迭代,for循环非常清楚它是如何初始化的,它是如何递增的,以及结束条件是什么。你的第一个循环不适合for循环,但你的第二个循环是。
这可以避免遗忘类型,他们初始化的内容以及所有内容。它还可以更容易地看到应该拆分成函数的内容。
str
更改为digits
。它不是一个字符串。
digits
的类型更改为short
。 digits
是一个单独的数字数组,没有一个会大于9.为每个数字分配64位是过度的。
unsigned long long int
可能会溢出str[20]
。这是代码中的另一个实际错误。 unsigned long long int
保证至少 64位,但可能更多。如果是,那将会溢出str
,其固定为20.您必须基于malloc
str
num_digits
的{{1}}内存,或使用{ {1}}从stdint.h
显式获取无符号的64位整数。
全部放在一起......
uint64_t
我们正在使用#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main()
{
// a will hold the number
uint64_t a=548763;
而不是uint64_t
malloc
。 YMMV,只要str
不能溢出。我选择了固定大小以避免引入内存分配,你可能还没有学到这一点。我保持不受约束,不必处理这个标志。
str
我把它留作// first we need to see the length of the number a
int num_digits = 0;
uint64_t b = a;
while( b>=10 ) {
b=b/10;
num_digits++;
}
循环,因为它不是一个简单的迭代器。根据需要声明变量(这将产生一个很好的小函数)。它将while
中的位数存储为一个简单的整数。
num_digits
这已被重写为short digits[20]= {0};
for( int i = num_digits; i >= 0; i-- ) {
digits[i]=a%10;
a=a/10;
}
循环,以明确这是一个简单的迭代器。 for
已复制到num_digits
,因此我们稍后可以使用i
。它下降到0. num_digits
现在是digits
s的数组,1个字节的整数;它只需要存储0到9之间的数字列表。
请注意,short
的初始化程序是非标准的。应该{}
将所有元素初始化为0。
{0}
我们仍然需要for( int i = 0; i <= num_digits; i++ ) {
printf("the value of str is \"%d\"\n", digits[i]);
}
来回顾num_digits
。
这可能是一项练习。在生产代码中,您可以使用digits
完成相同的操作。这也将处理负数,不需要无符号。
sprintf
请注意the types from stdint.h have their own printf format specifiers。 int64_t a=548763;
char str[22] = {0}; // 1 extra for the possible sign, 1 for the null byte.
sprintf(str, "%"PRId64, a);
for( int i = 0; str[i] != '\0'; i++ ) {
printf("the value of str is \"%c\"\n", str[i]);
}
是64位数字的PRIntf格式。它是一个宏,必须在引号之外才能扩展为自己的字符串。它利用了相邻的C字符串在编译时自动连接。
PRId64
答案 2 :(得分:0)
这是我最终按预期工作的最终代码。 我从来没有写过零指数。
我将str[i]=a%10;
更改为str[i-1]=a%10;
进行了一些其他的小改动,以使循环正常运行,因为它没有进行最后一次循环。谢谢大家的帮助。
#include <stdio.h>
int main()
{
// a will hold the number
unsigned long long int a=123456,i=0;
// str will hold the result which is the array
unsigned long long int str[20]= {0};
// first we need to see the length of the number a
long long int b=a;
while(b>0)
{
b=b/10;
i++;
}
// the length of the number a will be stored in variable i
// the while loop below will store the digit from the end of str to the
// the beginning
while(i>0)
{
str[i-1]=a%10;
a=a/10;
i--;
}
// only for test
printf("the value of str is \"%llu\"\n", str[1]); //[0]
return 0;
}