C uint作为指数
编辑:最初我转录了C uint作为指数,c,debugging,C,Debugging,编辑:最初我转录了I++而不是I-- 代码现在和以前一样,代码块中的代码可以编译并工作 为什么,如果无符号整数i代替int i在下面的代码段中,使用函数是否会导致segfault void insertion_sort_int_array(int * const Ints, unsigned int const len) { unsigned int pos; int key; int i; for (pos = 1; pos < len; ++
I++
而不是I--
代码现在和以前一样,代码块中的代码可以编译并工作
为什么,如果
无符号整数i使用code>代替int i
在下面的代码段中,使用函数是否会导致segfault
void insertion_sort_int_array(int * const Ints, unsigned int const len) {
unsigned int pos;
int key;
int i;
for (pos = 1; pos < len; ++pos) {
key = Ints[pos];
for (i = (pos - 1); (i >= 0) && Ints[i] > key; i--) {
Ints[i + 1] = Ints[i];
}
Ints[i + 1] = key;
}
}
void insertion\u sort\u int\u数组(int*const int,unsigned int const len){
无符号整数位置;
int键;
int i;
用于(pos=1;pos=0)和&Ints[i]>键;i--){
整数[i+1]=整数[i];
}
Ints[i+1]=键;
}
}
是什么使i+1保持在数组“int”的范围内?看起来数组中格式不正确的数据将导致您索引到不应该在其中的内存区域。是什么使i+1保持在数组“int”的范围内?看起来数组中格式不正确的数据会导致您索引到不应该在其中的内存区域。在任何情况下,发布的代码都会失败(可能是segfault,可能只是损坏内存)
内部循环从pos-1开始,在内存中向上扫描,,直到满足某个随机条件-它不会检查是否已通过数组的结尾,因此将愉快地运行,直到崩溃或它正在破坏的内存的(未定义的)内容恰好满足结尾条件
您可能打算在内存中向下扫描(使用循环中的i--),在这种情况下,它将失败,因为循环将达到0。从0中减去1会得到一个非常大的无符号正数,因此循环将永远不会结束(i>=0始终为真),它将访问冥王星区域的某个位置的内存。在任何情况下发布的代码都会失败(可能是segfault,可能只是损坏内存)
内部循环从pos-1开始,在内存中向上扫描,,直到满足某个随机条件-它不会检查是否已通过数组的结尾,因此将愉快地运行,直到崩溃或它正在破坏的内存的(未定义的)内容恰好满足结尾条件
您可能打算在内存中向下扫描(使用循环中的i--),在这种情况下,它将失败,因为循环将达到0。从0中减去1会得到一个非常大的无符号正数,因此循环永远不会结束(i>=0始终为真),它将访问冥王星区域的某个地方的内存。i
将[wrapparound]导致访问超出数组限制。
导入限制并与UINT\u MAX
进行比较,而不是以前的(i>=0)
解决了以下问题:
#include <limits.h>
void insertion_sort_int_array(int * const Integers, unsigned int const N)
{
unsigned int o;
int target;
unsigned int i;
for (o = 1; o < N; o++) {
target = Integers[o];
for (i = (o - 1); (i != UINT_MAX) && (Ints[i] > target); i--) {
Integers[i + 1] = Integers[i];
}
Integers[i + 1] = key;
}
}
#包括
无效插入\排序\整数数组(整数*常量整数,无符号整数常量N)
{
无符号整数o;
int目标;
无符号整数i;
对于(o=1;otarget);i--){
整数[i+1]=整数[i];
}
整数[i+1]=键;
}
}
i
将[wrapparound]导致访问超出数组限制。
导入限制并与UINT\u MAX
进行比较,而不是以前的(i>=0)
解决了以下问题:
#include <limits.h>
void insertion_sort_int_array(int * const Integers, unsigned int const N)
{
unsigned int o;
int target;
unsigned int i;
for (o = 1; o < N; o++) {
target = Integers[o];
for (i = (o - 1); (i != UINT_MAX) && (Ints[i] > target); i--) {
Integers[i + 1] = Integers[i];
}
Integers[i + 1] = key;
}
}
#包括
无效插入\排序\整数数组(整数*常量整数,无符号整数常量N)
{
无符号整数o;
int目标;
无符号整数i;
对于(o=1;otarget);i--){
整数[i+1]=整数[i];
}
整数[i+1]=键;
}
}
标准插入排序算法与代码之间的唯一区别在于,您正在递增i,而不是递减。那是你的问题。我敢打赌,在您实际编译和运行的代码中,在内部循环中有I,而不是I++。这就是为什么不带符号的i会起作用——它不能是负的,所以内部循环永远不会结束。你发帖时把代码抄错了吗
编辑:
好吧,现在你更改了发布的代码,这一切都是有意义的,对吗?当你将一个无符号的i减小至超过0时,它将下溢到INT_MAX,这将导致你访问数组边界之外的内存
标准插入排序算法与代码之间的唯一区别在于,您正在递增i,而不是递减。那是你的问题。我敢打赌,在您实际编译和运行的代码中,在内部循环中有I,而不是I++。这就是为什么不带符号的i会起作用——它不能是负的,所以内部循环永远不会结束。你发帖时把代码抄错了吗
编辑:
好吧,现在你更改了发布的代码,这一切都是有意义的,对吗?当你将一个无符号的i减小至超过0时,它将下溢到INT_MAX,这将导致你访问数组边界之外的内存
为什么,如果不带符号的int i;使用
而不是int i;在代码段中
下面,使用函数是否会产生结果
在断层中
void insertion_sort_int_array(int * const Ints, unsigned int const len) {
unsigned int pos;
int key;
int i;
for (pos = 1; pos < len; ++pos) {
key = Ints[pos];
for (i = (pos - 1); (i >= 0) && Ints[i] > key; i--) {
Ints[i + 1] = Ints[i];
}
Ints[i + 1] = key;
}
}
因为对于unsigned int i
,i>=0
始终为真,所以for循环不太可能在需要时终止
如果计数器未签名,则在向后循环(从高到低)时应始终非常小心
为什么,如果不带符号的int i;使用
而不是int i;在代码段中
下面,使用函数是否会产生结果
在断层中
void insertion_sort_int_array(int * const Ints, unsigned int const len) {
unsigned int pos;
int key;
int i;
for (pos = 1; pos < len; ++pos) {
key = Ints[pos];
for (i = (pos - 1); (i >= 0) && Ints[i] > key; i--) {
Ints[i + 1] = Ints[i];
}
Ints[i + 1] = key;
}
}
因为对于unsigned int i
,i>=0
始终为真,所以for循环不太可能在需要时终止
如果您的计数器未签名,则在向后循环(从高到低)时应始终非常小心。如果我未签名,(i>=0)的目的是什么=