定义长整型长数组
Defining array of long long int
我正在尝试生成一个数组,它将从2^0到2^63的2次方。我用的是unsigned long long int。但是当我打印所有的值,它打印到2^30,然后它溢出。编译器是GNU GCC版本4.8.1。代码如下:
unsigned long long int a[65],i;
a[0]=1;
for(i=1;i<65;i++) {
a[i]=2<<(i-1);
printf("i=%d a[i]=%lldn",i, a[i]);
}
下面是输出
i=1 a[i]=2
i=2 a[i]=4
i=3 a[i]=8
i=4 a[i]=16
i=5 a[i]=32
i=6 a[i]=64
i=7 a[i]=128
i=8 a[i]=256
i=9 a[i]=512
i=10 a[i]=1024
i=11 a[i]=2048
i=12 a[i]=4096
i=13 a[i]=8192
i=14 a[i]=16384
i=15 a[i]=32768
i=16 a[i]=65536
i=17 a[i]=131072
i=18 a[i]=262144
i=19 a[i]=524288
i=20 a[i]=1048576
i=21 a[i]=2097152
i=22 a[i]=4194304
i=23 a[i]=8388608
i=24 a[i]=16777216
i=25 a[i]=33554432
i=26 a[i]=67108864
i=27 a[i]=134217728
i=28 a[i]=268435456
i=29 a[i]=536870912
i=30 a[i]=1073741824
i=31 a[i]=-2147483648
i=32 a[i]=0
i=33 a[i]=2
i=34 a[i]=4
i=35 a[i]=8
i=36 a[i]=16
i=37 a[i]=32
i=38 a[i]=64
i=39 a[i]=128
i=40 a[i]=256
i=41 a[i]=512
i=42 a[i]=1024
i=43 a[i]=2048
i=44 a[i]=4096
i=45 a[i]=8192
i=46 a[i]=16384
i=47 a[i]=32768
i=48 a[i]=65536
i=49 a[i]=131072
i=50 a[i]=262144
i=51 a[i]=524288
i=52 a[i]=1048576
i=53 a[i]=2097152
i=54 a[i]=4194304
i=55 a[i]=8388608
i=56 a[i]=16777216
i=57 a[i]=33554432
i=58 a[i]=67108864
i=59 a[i]=134217728
i=60 a[i]=268435456
i=61 a[i]=536870912
i=62 a[i]=1073741824
i=63 a[i]=-2147483648
i=64 a[i]=0
我也尝试过使用int64_t,但结果是相同的。如果我通常输入
unsigned long long int int lli = 9223372036854775807;
并打印它的值,它就工作了。我哪里做错了?
您的问题在此代码:a[i] = 2 << (i-1);
2
被假定为int
类型,因为在大多数c++编译器中它是32位的。
你需要用。
覆盖它。 a[i] = 2ULL << (i-1);
您需要特别注意与移位操作符一起使用的类型,移位操作数的大小为未定义行为并且这里可能发生任何事情(示例),对于字面量需要更多的预防措施,因为忘记了后缀。
问题出在这一行:
2<<(i-1)
^
2
是一个整数字面值,因此结果是一个int而不是unsigned long long您可以使用ULL
后缀来修复这个问题。
使用大于提升左操作数位长度的移位也是未定义的行为。在使用printf
时也有未定义的行为。您使用了不正确的格式说明符,在这两种情况下您都应该使用%llu
。
使用正确的警告标志可能会帮助您捕获所有这些错误,例如使用以下标志-fsanitize=undefined -Wall -Wextra -Wconversion -pedantic
和clang
给出以下警告:
warning: implicit conversion changes signedness: 'int' to 'unsigned long long' [-Wsign-conversion]
a[i]=2<<(i-1);
~~^~~~~~~
warning: format specifies type 'int' but the argument has type 'unsigned long long' [-Wformat]
printf("i=%d a[i]=%lldn",i, a[i]);
~~ ^
%llu
和以下运行时错误:
runtime error: left shift of 2 by 31 places cannot be represented in type 'int'
其他答案已经回答了您的问题,但是您的代码中还存在一些其他问题。
要展开其他答案,请记住,C表达式的类型通常由表达式本身决定,而不是由它出现的上下文决定。你有:
a[i]=2<<(i-1);
左侧赋值语句类型为unsigned long long int
,不影响右侧赋值语句类型为int
的求值,而<<
赋值语句导致int
溢出。
没有必要将数组中的元素0作为特例来处理。
与其写2 << (i-1)
,或者更正确的2ULL << (i-1)
,不如写1ULL << i
更直接。
您正在使用错误的printf
格式字符串为您的变量。i
的类型为unsigned long long
;"%d"
要求参数类型为int
。但由于i
只从0到65计数,它也可能是int
。a
的元素是unsigned long long int
类型的,但是您使用的格式是signed long long int
。
这是你的程序代码片段的修改版本,充实成一个完整的程序,并纠正了上面的问题:
#include <stdio.h>
int main(void) {
unsigned long long int a[65];
int i;
for(i=0;i<65;i++) {
a[i] = 1ULL << i;
printf("i=%d a[i]=%llun", i, a[i]);
}
}
使用%llu来扫描unsigned long long int而不是%lld,你在扫描
- C 字符串返回字符串的整数/双精度/长整型值
- 无法在 Arduino 中uint8_t数组转换为无符号长整型数组
- JNI 日期值转换问题,在C++中获取不同的长整型值
- 将长整型值打印为带有前导零的十六进制
- 为什么在传递长整型时调用具有两个双精度类型的参数的重载函数?
- 将元组和整型实例合并到引用元组中
- 提升不良词法强制转换:将字符串转换为无符号长整型时,无法将源类型值解释为目标
- 将最小值整数转换为无符号长整型
- 如何将小端格式的QByteArray转换为无符号长整型
- 无符号长整型和无符号 int 之间有什么区别,这 2 种类型应该如何在 c# 中封送?
- 将 BYTE 数组转换为无符号长整型
- 如何设置,在C/C++中清除一个长整型数
- 如何将SHA1转换为无符号长整型数组[5]
- 我需要以相反的方式复制一个长整型数组,我需要系统函数,例如 memcpy 有没有
- 如何将字节数组转换为整数类型(整数、长整型、短型等)"安眠安"?
- 在 C++ 中获取长整型和双精度型模数的准确方法
- 复制存储在空指针的整型数组到整型数组
- 定义长整型长数组
- 指向char数组的整型指针
- 比较浮点数组和整型数组