打印负数

时间:2016-12-05 11:36:03

标签: c arrays sorting

这是一个排序整数的程序。

#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

什么似乎是问题?

3 个答案:

答案 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