我在c++;其中,计算两个小整数相加的语句溢出到一个长值中 我最近遇到了一个我不理解的奇怪的C++错误。这是我的密码: #include <bits/stdc++.h> using namespace std; typedef vector <int> vi; typedef pair <int, int> ii; #define ff first #define ss second #define pb push_back const int N = 2050; int n, k, sum = 0; vector <ii> a; vi pos; int main (void) { cin >> n >> k; for (int i = 1; i < n+1; ++i) { int val; cin >> val; a.pb(ii(val, i)); } cout << a.size()-1 << " " << k << " " << a.size()-k-1 << "\n"; }

我在c++;其中,计算两个小整数相加的语句溢出到一个长值中 我最近遇到了一个我不理解的奇怪的C++错误。这是我的密码: #include <bits/stdc++.h> using namespace std; typedef vector <int> vi; typedef pair <int, int> ii; #define ff first #define ss second #define pb push_back const int N = 2050; int n, k, sum = 0; vector <ii> a; vi pos; int main (void) { cin >> n >> k; for (int i = 1; i < n+1; ++i) { int val; cin >> val; a.pb(ii(val, i)); } cout << a.size()-1 << " " << k << " " << a.size()-k-1 << "\n"; },c++,c++11,C++,C++11,它返回: 4 5 4294967295 但当我将声明从: int n, k, sum = 0; 致: 然后程序返回正确的值,即: 4 5 -1 我不明白为什么程序会这样,因为-1不应该超过整数值。谁能给我解释一下吗?我真的很感激你的帮助 感谢vector::size返回size_t(无符号),表达式a.size()-k-1的计算结果为无符号类型,因此最终会出现下溢 显然,在您的机器上,size\u t是32位整数,而long是64位整数大小\u t始终是无符号类型,因此您可以得到: cou

它返回:

4 5 4294967295
但当我将声明从:

int n, k, sum = 0;
致:

然后程序返回正确的值,即:

4 5 -1
我不明白为什么程序会这样,因为-1不应该超过整数值。谁能给我解释一下吗?我真的很感激你的帮助


感谢vector::size返回size_t(无符号),表达式
a.size()-k-1
的计算结果为无符号类型,因此最终会出现下溢

显然,在您的机器上,
size\u t
是32位整数,而
long
是64位整数<代码>大小\u t始终是无符号类型,因此您可以得到:

cout << a.size()      -   1
//        ^ unsigned      ^ promoted to unsigned
//      output as uint32_t
//                ^ (!)
a.size() - k - 1
// ^ promoted to long long, as of smaller size!
// -> overall expression is  int64_t
//                          ^ (!)
cout的整体表达式是int64\t
//                          ^ (!)
如果
size\u t
也是64位的,那么打印的两个值(应该是18446744073709551615)就不会有任何差异,那么有符号的
long-long k
int64\u t
)就会升级为无符号(
uint64\u t

注意,<>代码> StistalQuasic(-1)总是根据C++代码转换为:<代码> STD::MultIcILimeLimult::Max()/<代码>


关于
大小\u t
的旁注:这是一种无符号整数类型,其大小足以容纳系统上为对象分配的最大大小,因此位大小取决于硬件,最终与内存地址总线的位大小相关(二的第一次幂不小于).

不要直接包含
位的任何内容。这些文件仅设计为包含在标准标题中,然后才应该包含这些文件。
\define pb push_back
也不要这样做。虽然它为您节省了一些打字时间,但它使代码(更)难以阅读,因为任何有经验的编码人员都知道
push_back
,而
pb
需要单独记住(或者编码人员必须再次查找)…
谢谢您的建议,我非常感谢您的建议
4 5 -1
cout << a.size()      -   1
//        ^ unsigned      ^ promoted to unsigned
//      output as uint32_t
//                ^ (!)
a.size() - k - 1
// ^ promoted to long long, as of smaller size!
// -> overall expression is  int64_t
//                          ^ (!)