这是一个排序整数的程序。
#include <stdio.h>
int main(void) {
int n, i, j, k;
int nmbr[100];
printf("\n How many numbers ? ");
scanf("%d", &n);
printf("\n");
for (i = 0; i < n; ++i) {
printf(" Number %d : ", i + 1);
scanf("%d", &nmbr[i]);
}
for (i = 0; i < n; ++i) {
for (j = 0; j < n; ++j) {
if (nmbr[j] > nmbr[j + 1]) {
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
}
printf("\n Numbers after sorting : \n");
for (i = 0; i < n; ++i) {
printf (" %d", nmbr[i]);
}
return 0;
}
它运行正常,但是当我输入一个包含2位以上数字的数字时,打印的第一个数字是负数且非常大。我也没有得到最后一个整数。我输入N
作为4
,然后我输入的数字是25,762,588和34.我得到的结果是:
-1217260830 25 34 588
什么似乎是问题?
答案 0 :(得分:3)
您的代码中存在多个问题:
您不检查scanf()
的返回值。如果这些输入操作中的任何一个失败,则目标值保持未初始化状态,调用未定义的行为并可能产生垃圾输出。
您不会验证用户提供的值的数量最多为100
。如果n
太大,读取循环将导致缓冲区溢出。
您的排序逻辑存在缺陷:在嵌套循环中,您引用的nmbr[j + 1]
超出了从用户读取的值。这会调用未定义的行为:可能导致垃圾值出现在输出中。
以下是更正后的版本:
#include <stdio.h>
int main(void) {
int n, i, j, k;
int nmbr[100];
printf("\n How many numbers ? ");
if (scanf("%d", &n) != 1 || n > 100) {
printf("input error\n");
return 1;
}
printf("\n");
for (i = 0; i < n; ++i) {
printf(" Number %d : ", i + 1);
if (scanf("%d", &nmbr[i]) != 1) {{
printf("input error\n");
return 1;
}
}
for (i = 0; i < n; ++i) {
for (j = 0; j < n - 1; ++j) {
if (nmbr[j] > nmbr[j + 1]) {
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
}
printf("\n Numbers after sorting :\n");
for (i = 0; i < n; ++i) {
printf (" %d", nmbr[i]);
}
printf("\n");
return 0;
}
答案 1 :(得分:2)
您的排序逻辑错误。它应该是:
for (i = 0; i < n; ++i){
for (j = 0; j < (n-1); ++j){
if (nmbr[j] > nmbr[j + 1]){
k = nmbr[j];
nmbr[j] = nmbr[j + 1];
nmbr[j + 1] = k;
}
}
当您使用j
迭代第二个循环时,您正尝试访问数组的界限。这导致了垃圾值。
根据涉及4个元素的示例,当您尝试访问j+1
时,它将尝试在第二个循环的最后一次迭代中访问nmbr [3 + 1],这会导致越界访问。
答案 2 :(得分:0)
问题在于其他编码员所建议的排序逻辑。但是初始化变量总是很好的编码习惯。如果只处理正数,也可以使用限定符。
unsigned int n = 0 , i = 0, j = 0, k = 0;
unsigned int nmbr[100] = {0};
如果您已经初始化它们,那么您的程序将会跟随,这可能会帮助您自己跟踪问题。
0 25 34 588