Help, the program works, but in my opinion, it is not at all optimal, and generally a trash code ... Point out the errors, and how best to do it. And also help, please, how instead of a heap of queues to make an array of queues, thanks in advance ...

#include <stdio.h> #include <stdlib.h> #include <time.h> #include <locale.h> #define QMAX 100 struct queue { int qu[QMAX]; int rear, frnt; }; void outputmas(int *mass, int n) { int i; printf("\n"); for (i = 0; i < n; i++) printf("%d ", mass[i]); //вывод сгенерированного массива printf("\n"); } void init(struct queue *q) { q->frnt = 1; q->rear = 0; return; } void insert(struct queue *q, int x) { if (q->rear < QMAX - 1) { q->rear++; q->qu[q->rear] = x; } else printf("Очередь полна!\n"); return; } int isempty(struct queue *q) { if (q->rear < q->frnt) return(1); else return(0); } void print(struct queue *q) { int h; if (isempty(q) == 1) { printf("Очередь пуста!\n"); return; } for (h = q->frnt; h <= q->rear; h++) printf("%d ", q->qu[h]); return; } int remove(struct queue *q) { int x, h; if (isempty(q) == 1) { printf("Очередь пуста!\n"); return(0); } x = q->qu[q->frnt]; for (h = q->frnt; h < q->rear; h++) { q->qu[h] = q->qu[h + 1]; } q->rear--; return(x); } int stepen(int num, int n) { int i, num1; num1 = 1; for (i = 0; i < n; i++) { num1 = num1*num; } return (num1); } int run(int num, int run) { int x; x = num%stepen(10, run + 1) / stepen(10, run); return(x); getchar(); } int sort(int *mass, int *massq ,int number_of_el, int runn) { struct queue *q0,*q1,*q2,*q3,*q4,*q5,*q6,*q7,*q8,*q9; int razr; q0 = (queue*)malloc(sizeof(queue)); q1 = (queue*)malloc(sizeof(queue)); q2 = (queue*)malloc(sizeof(queue)); q3 = (queue*)malloc(sizeof(queue)); q4 = (queue*)malloc(sizeof(queue)); q5 = (queue*)malloc(sizeof(queue)); q6 = (queue*)malloc(sizeof(queue)); q7 = (queue*)malloc(sizeof(queue)); q8 = (queue*)malloc(sizeof(queue)); q9 = (queue*)malloc(sizeof(queue)); init(q0); init(q1); init(q2); init(q3); init(q4); init(q5); init(q6); init(q7); init(q8); init(q9); for (int el = 0; el < number_of_el; el++) { razr = run(mass[el], runn); switch (razr) { case 0: insert(q0, mass[el]); break; case 1: insert(q1, mass[el]); break; case 2: insert(q2, mass[el]); break; case 3: insert(q3, mass[el]); break; case 4: insert(q4, mass[el]); break; case 5: insert(q5, mass[el]); break; case 6: insert(q6, mass[el]); break; case 7: insert(q7, mass[el]); break; case 8: insert(q8, mass[el]); break; case 9: insert(q9, mass[el]); break; } } for (int i = 0; i < number_of_el; i++) { for (;;) { if (!isempty(q0)) { massq[i] = remove(q0); i++; } else break; } for (;;) { if (!isempty(q1)) { massq[i] = remove(q1); i++; } else break; } for (;;) { if (!isempty(q2)) { massq[i] = remove(q2); i++; } else break; } for (;;) { if (!isempty(q3)) { massq[i] = remove(q3); i++; } else break; } for (;;) { if (!isempty(q4)) { massq[i] = remove(q4); i++; } else break; } for (;;) { if (!isempty(q5)) { massq[i] = remove(q5); i++; } else break; } for (;;) { if (!isempty(q6)) { massq[i] = remove(q6); i++; } else break; } for (;;) { if (!isempty(q7)) { massq[i] = remove(q7); i++; } else break; } for (;;) { if (!isempty(q8)) { massq[i] = remove(q8); i++; } else break; } for (;;) { if (!isempty(q9)) { massq[i] = remove(q9); i++; } else break; } } mass = massq; outputmas(massq, number_of_el); if (runn < 2) { runn++; sort(mass, massq, number_of_el, runn); } return 0; } int main() { srand(time(NULL)); setlocale(LC_CTYPE, "Rus"); int n=12, i, algorythm, min=1, max=900, ra, moveNum, runn=0; ra = max - min + 1; int *mass = new int[n]; int *massq = new int[n]; for (i = 0; i < n; i++) { mass[i] = rand() % ra + min; } printf("Случайный массив: "); outputmas(mass, n); sort(mass, massq, n, runn); getchar(); return 0; } 
  • Write loops with else break; it is very strange. You can allocate memory in one fell swoop at all: x = calloc(n, sizeof(*x)); (if I remember correctly the order of the arguments). All these repetitions can be minimized in 10-15 lines of code. - 0andriy
  • I did not understand how to do all this, and where to write x = calloc ... (Well, I understand that there will be no x) Can you please explain more, I beg you? - Dima Ivanov
  • Sorry, I’ll definitely not do for you. Want to learn - learn, want results - hire someone who will. - 0andriy
  • one
    Then I apologize, I will continue to try to understand. Thanks for your reply. - Dima Ivanov

1 answer 1

From gross mistakes:

  1. You have a mixture of C and C ++ (using the operator new );
  2. Your remove function overrides the standard function from stdio.h ;
  3. Instead of while , a strange construction with infinite for , if and break ;
  4. There are memory leaks (each call to malloc must be matched by a free call);
  5. There are unused variables.

As for the array of structures, it is created very simply:

 static const int q_count = 10; queue_s *q = malloc(sizeof(queue_s) * q_count); 

Well, and having on hands an array of structures, it is possible to get rid of the repeating code, addressing them on an index. Pay attention that the operation of taking the address of the &q[i] structure when transferring it to the function is used, because q[i] is actually the i-th structure (not a pointer).

Refactored code:

 #include <stdio.h> #include <stdlib.h> #include <time.h> #include <locale.h> #include <stdbool.h> #define QMAX 100 typedef struct { int qu[QMAX]; int rear, frnt; } queue_s; void outputmas(int *mass, int n) { printf("\n"); for (int i = 0; i < n; i++) printf("%d ", mass[i]); //вывод сгенерированного массива printf("\n"); } void init(queue_s *q) { q->frnt = 1; q->rear = 0; } void insert(queue_s *q, int x) { if (q->rear < QMAX - 1) { q->rear++; q->qu[q->rear] = x; } else printf("Очередь полна!\n"); } bool isempty(queue_s *q) { return q->rear < q->frnt; } void print(queue_s *q) { if (isempty(q)) { printf("Очередь пуста!\n"); } else { for (int h = q->frnt; h <= q->rear; h++) printf("%d ", q->qu[h]); } } int qremove(queue_s *q) { if (isempty(q)) { printf("Очередь пуста!\n"); return 0; } int x = q->qu[q->frnt]; for (int h = q->frnt; h < q->rear; h++) { q->qu[h] = q->qu[h + 1]; } q->rear--; return x; } int stepen(int num, int n) { int num1 = 1; for (int i = 0; i < n; i++) { num1 *= num; } return num1; } int run(int num, int run) { return num % stepen(10, run + 1) / stepen(10, run); } int sort(int *mass, int *massq ,int number_of_el, int runn) { static const int q_count = 10; queue_s *q = malloc(sizeof(queue_s) * q_count); for (int i = 0; i < q_count; i++) { init(&q[i]); } for (int el = 0; el < number_of_el; el++) { int razr = run(mass[el], runn); if (razr >= 0 && razr < q_count) { insert(&q[razr], mass[el]); } } for (int i = 0; i < number_of_el; i++) { for (int j = 0; j < q_count; j++) { while ( !isempty(&q[j]) ) { massq[i] = qremove(&q[j]); i++; } } } free(q); mass = massq; outputmas(massq, number_of_el); if (runn < 2) { runn++; sort(mass, massq, number_of_el, runn); } return 0; } int main() { srand(time(NULL)); setlocale(LC_CTYPE, "Rus"); int n=12, min=1, max=900, runn=0; int ra = max - min + 1; int *mass = malloc(sizeof(int) * n); int *massq = malloc(sizeof(int) * n); for (int i = 0; i < n; i++) { mass[i] = rand() % ra + min; } printf("Случайный массив: "); outputmas(mass, n); sort(mass, massq, n, runn); free(mass); free(massq); getchar(); return 0; } 
  • calloc () is still a bit better. - 0andriy
  • one
    @ 0andriy On the contrary, it does unnecessary memory reset. - zed
  • By the way, not always. If you read from it, it’s not even a fact that it is from the allocated memory. Read at your leisure: vorpus.org/blog/why-does-calloc-exist - 0andriy
  • @ 0andriy Not always, but here 408 * 10 = 4Kb stands out, and on such sizes calloc equivalent to malloc + memset . So in this particular case, this function will do an extra memory reset. - zed