如何在此代码中制作数组的副本并使用它

时间:2016-07-13 03:57:46

标签: c arrays

所以我有这个代码,它根据用户输入随机生成一个整数数组,并按升序和降序排列元素。但是,目前,代码只打印两次降序。所以我想知道如何制作数组ascd的副本,并在组织降序的代码片段中使用副本。我只是一个初学者,所以如果这是一个愚蠢的问题我很抱歉,并感谢我能得到的所有指导。这是我的代码:

#include <stdio.h>
#include <string.h> 
#include <time.h>
#include <stdlib.h>
int main (){ 


int x; 
printf("Enter the size of your array\n");//User is entering number of elements
scanf("%d", &x); 
int ascd[x]; //Array 
int c; 
int d;
int e; 
int kk = 0;
int temp;
int tempother;
int turtle; 

for(c = 0; c<x; c++){//Randomly generating elements
    srand(time(0)); 
    ascd[kk] = (rand() %100) + 1;
}

for(c = 0; c<x; c++){ //Ascending order
    for(d = 0; d<(x-c-1); d++){
        if(ascd[d] > ascd[d+1]){
                temp = ascd[d]; 
                ascd[d] = ascd[d+1]; 
                ascd[d+1] = temp; 
                }

                            }

               }




for(turtle = 0; turtle<x; turtle++){//Descending order
    for(e = 0; e<(x-turtle-1); e++){
        if(ascd[e] < ascd[e+1]){
                tempother = ascd[e]; 
                ascd[e] = ascd[e+1]; 
                ascd[e+1] = tempother; 
                }

                            }

               }




printf("The ascending order is\n\n"); 
         for(c = 0; c<x; c++){
     printf("%d\n", ascd[c]);
     }


printf("\n\nThe descending order is\n\n"); 
         for(turtle = 0; turtle<x; turtle++){
         printf("%d\n", ascd[turtle]);
         }   




}

3 个答案:

答案 0 :(得分:3)

您需要考虑许多其他问题。首先,始终,验证用户输入。如果没有别的,使用scanf系列函数,请确保已成功执行预期的转化次数。 e.g。

int x = 0;
printf ("\n enter the number of elements for your array: ");
if (scanf ("%d", &x) != 1) {    /* always validate user input */
    fprintf (stderr, "error: invalid input, integer required.\n");
    return 1;
}
int ascd[x], desc[x];

接下来,您只需要将随机数生成器播种一次。将srand (time (NULL));移出循环。

虽然不是必需条件,但最好将VLA初始化为零(或某些数字,因为您无法提供初始化程序),以消除在迭代数组时无意识读取未初始化值的可能性(您在这种情况下可以考虑填充初始化,使memset在这里可选,但是你不会立即循环并填写所有情况。如果你没有立即填充数组,那么如下所示就足够了,例如

memset (ascd, 0, x * sizeof *ascd); /* good idea to zero your VLA */

填充数组后,如果您希望保留升序和降序排序,则简单的memcpy将复制数组,例如

for (int i = 0; i < x; i++)            /* x random values 1 - 100 */
    ascd[i] = (rand () % 100) + 1;

memcpy (desc, ascd, x * sizeof *ascd);       /* copy ascd to desc */

剩下的只是一点点清理。抵制为代码中的每个值创建(变量)的冲动。这很快变得难以理解。虽然我更喜欢C89声明,但for块内的C99 / C11声明很方便,例如:

for (int i = 0; i < x; i++)                    /* ascending order */
    for (int j = 0; j < (x - i - 1); j++)
        if (ascd[j] > ascd[j + 1]) {
            int temp = ascd[j];
            ascd[j] = ascd[j + 1];
            ascd[j + 1] = temp;
        }

将所有部分放在一起,并注意到main()int类型,因此return是一个值,您可以按照以下方式整理。你的风格完全取决于你,但目标应该是可读性。 e.g。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

int main (void) {

    int x = 0;
    printf ("\n enter the number of elements for your array: ");
    if (scanf ("%d", &x) != 1) {    /* always validate user input */
        fprintf (stderr, "error: invalid input, integer required.\n");
        return 1;
    }
    int ascd[x], desc[x];

    srand (time (NULL));                /* you only need do this once */
    memset (ascd, 0, x * sizeof *ascd); /* good idea to zero your VLA */

    for (int i = 0; i < x; i++)            /* x random values 1 - 100 */
        ascd[i] = (rand () % 100) + 1;

    memcpy (desc, ascd, x * sizeof *ascd);       /* copy ascd to desc */

    for (int i = 0; i < x; i++)                    /* ascending order */
        for (int j = 0; j < (x - i - 1); j++)
            if (ascd[j] > ascd[j + 1]) {
                int temp = ascd[j];
                ascd[j] = ascd[j + 1];
                ascd[j + 1] = temp;
            }

    for (int i = 0; i < x; i++)                   /* descending order */
        for (int j = 0; j < (x - i - 1); j++)
            if (desc[j] < desc[j + 1]) {
                int temp = desc[j];
                desc[j] = desc[j + 1];
                desc[j + 1] = temp;
            }

    printf ("\n the ascending order is\n\n");
    for (int i = 0; i < x; i++) {
        if (i && !(i % 10)) putchar ('\n');
        printf (" %3d", ascd[i]);
    }

    printf ("\n\n the descending order is\n\n");
    for (int i = 0; i < x; i++) {
        if (i && !(i % 10)) putchar ('\n');
        printf (" %3d", desc[i]);
    }
    putchar ('\n');

    return 0;
}

示例使用/输出

$ ./bin/sort_copy

 enter the number of elements for your array: 100

 the ascending order is

   1   1   4   4   5   5   7   8   8   9
  10  13  16  16  17  20  22  22  22  23
  24  24  25  27  29  29  33  35  35  35
  37  38  40  41  41  41  41  42  44  45
  46  48  48  48  49  50  53  54  56  57
  58  59  61  61  63  64  65  65  66  66
  67  68  68  70  71  73  74  74  74  75
  76  80  80  80  80  82  84  84  85  85
  85  85  86  88  88  89  89  90  91  91
  91  92  92  93  93  93  96  99 100 100

 the descending order is

 100 100  99  96  93  93  93  92  92  91
  91  91  90  89  89  88  88  86  85  85
  85  85  84  84  82  80  80  80  80  76
  75  74  74  74  73  71  70  68  68  67
  66  66  65  65  64  63  61  61  59  58
  57  56  54  53  50  49  48  48  48  46
  45  44  42  41  41  41  41  40  38  37
  35  35  35  33  29  29  27  25  24  24
  23  22  22  22  20  17  16  16  13  10
   9   8   8   7   5   5   4   4   1   1

仔细看看,如果您有任何问题,请告诉我。

排序 qsort

继续评论,qsort是一个优化的排序例程,它是C标准库的一部分(在stdlib.h中),无论您拥有何种类型的数据,它都是首选排序函数排序。通常捕获新C程序员的唯一要求是需要编写一个比较函数以传递给qsort,以便qsort知道您希望如何对对象集合进行排序。 qsort将通过将指向值的指针传递给您编写的compare函数来比较两个元素。无论您要排序什么,比较的声明都是相同的,例如。

int compare (const void *a, const void *b);

你知道你正在排序整数值,所以你需要做的就是升序排序是写一个函数,如果a > b返回一个正值 ,如果它们相等则返回,如果b > a,则返回负值。简单的方法就是写

int compare (const void *a, const void *b) {
    int x = *(int *)a;
    int y = *(int *)b;
    return x - y;
}

满足升序的排序要求,并按降序排序return y - x; - ,但存在问题。如果xy碰巧是大的正值和大的负值,则x - y可能会超过整数的最大值(或最小值)(例如溢出) ,因为结果不适合整数值。)

解决方案很简单。您可以执行相同的比较,但使用不等式的结果,例如返回(a > b) - (a < b)进行升序比较,(a < b) - (a > b)进行降序比较。 (此方案适用于所有数字类型,您只需要调整演员表)。迈出不平等的一步。在升序的情况下,如果a > b返回1(例如return 1 - 0;)。如果它们相等,则不等式返回00 - 0),最后返回a < b,返回的值为-10 - 1)。

虽然您可以继续明确声明xy变量,但通常会在比较中看到它与强制转换一起编写,从而无需使用xy完全/* integer comparison ascending (prevents overflow) */ int cmpascd (const void *a, const void *b) { /* (a > b) - (a < b) */ return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b); } 个变量,例如

qsort

将这些部分放在一起,可以使用#include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #define ROW 10 int cmpascd (const void *a, const void *b); int cmpdesc (const void *a, const void *b); void prnarr (int *a, int n, int row); int main (void) { int x = 0; printf ("\n enter the number of elements for your array: "); if (scanf ("%d", &x) != 1) { /* always validate user input */ fprintf (stderr, "error: invalid input, integer required.\n"); return 1; } int ascd[x], desc[x]; srand (time (NULL)); /* you only need do this once */ memset (ascd, 0, x * sizeof *ascd); /* good idea to zero your VLA */ for (int i = 0; i < x; i++) /* x random values 1 - 100 */ ascd[i] = (rand () % 100) + 1; memcpy (desc, ascd, x * sizeof *ascd); /* copy ascd to desc */ qsort (ascd, x, sizeof *ascd, cmpascd); /* qsort ascending */ qsort (desc, x, sizeof *desc, cmpdesc); /* qsort descending */ printf ("\n the ascending order is\n\n"); prnarr (ascd, x, ROW); printf ("\n\n the descending order is\n\n"); prnarr (desc, x, ROW); putchar ('\n'); return 0; } /* integer comparison ascending (prevents overflow) */ int cmpascd (const void *a, const void *b) { /* (a > b) - (a < b) */ return (*(int *)a > *(int *)b) - (*(int *)a < *(int *)b); } /* integer comparison descending */ int cmpdesc (const void *a, const void *b) { /* (a < b) - (a > b) */ return (*(int *)a < *(int *)b) - (*(int *)a > *(int *)b); } void prnarr (int *a, int n, int row) { for (int i = 0; i < n; i++) { printf (" %3d", a[i]); if (i && !((i + 1) % row)) putchar ('\n'); } } 而不是低效的嵌套循环(并将打印数组例程移动到它自己的函数)来编写相同的程序,如下所示,

-Wall -Wextra

与第一个答案一样,试一试,如果您有任何疑问,请告诉我。 (并且记住始终使用最小-pedantic进行编译以启用大多数编译器警告 - 并在您认为代码可靠之前修复生成的任何警告 - 您不会遇到可以理解并安全地忽略警告的任何情况任何时候)添加gcc以查看几乎所有可以生成的警告。 (如果你在Websters中查找 pedantic ,你就会明白为什么这个名字很合适。)只是FYI,我用来编译代码的$ gcc -Wall -Wextra -pedantic -std=c11 -Ofast -o bin/sort_copy sort_copy.c 编译器字符串是:

{{1}}

答案 1 :(得分:0)

您打印最后一个数组两次,您可以通过在完成升序操作后立即打印数组的值来获得升序数组输出。

答案 2 :(得分:0)

创建另一个数组来存储降序项。您可以反转升序数组以创建降序数组。试试这个代码。     #包括     #包括     #包括     #包括     int main(){

int x;
printf("Enter the size of your array\n");//User is entering number of elements
scanf("%d", &x);
int ascd[x]; //Array
int desc[x];
int c;
int d;
int e;
int kk = 0;
int temp;
int tempother;
int turtle;
int z=0;

for(c = 0; c<x; c++){//Randomly generating elements
    srand(time(0));
    ascd[kk] = (rand() %100) + 1;
}

for(c = 0; c<x; c++){ //Ascending order
    for(d = 0; d<(x-c-1); d++){
        if(ascd[d] > ascd[d+1]){
                temp = ascd[d];
                ascd[d] = ascd[d+1];
                ascd[d+1] = temp;
                }

                            }

               }




for(turtle = x-1; turtle>=0; turtle--){//Descending order
        desc[z]=ascd[turtle];
        z++;


    }




printf("The ascending order is\n\n");
         for(c = 0; c<x; c++){
     printf("%d\n", ascd[c]);
     }


printf("\n\nThe descending order is\n\n");
         for(turtle = 0; turtle<x; turtle++){
         printf("%d\n", desc[turtle]);
         }




}