Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[54.89.70.161] |
|
Сообщ.
#1
,
|
|
|
Здравствуйте. Помогите, пожалуйста, с задачей: Дана матрица размером n*n. Проверить упорядочены ли элементы столбцов матрицы. Если нет, то упорядочить их в порядке возрастания методом просеивания.
У меня в программе используется динамическая матрица с указателями и при сортировке выкидывает из программы. Я подозреваю, что там происходит выход за границы матрицы. Вот мой исходный код: #include <stdio.h> #include <stdlib.h> #include <conio.h> #include <malloc.h> int menu(int kp, char*NAZ[]); int main(void); void vvod(int n, int ***A); void vivod(int n, int **A); int zadacha1(int n, int kk, int pp, int **A); int zadacha2(int n, int **A); int menu(int kp, char*NAZ[]) { int k, i; for (i = 0; i < kp; i++) printf("\n %d %s", i + 1, NAZ[i]); printf("\n\n Viberite punct menu ->"); scanf("%d",&k); return k; } void vvod(int n, int ***D) { int i, j; printf("Vvedite razmernost matrici n="); scanf("%d", n); if (*D != NULL) free(*D); int **A = (int **) malloc (n * sizeof (int *)); for (i = 0; i < n; i++) A[i] = (int *) malloc(n * sizeof (int)); for (i = 0; i < n; i++) for (j = 0; j < n; j++) { printf("A[%d][%d]=", i,j); scanf("%d", &A[i][j]); } *D = A; } void vivod(int n, int **A) { int i,j; for (i = 0; i < n; i++) { for (j = 0; j < n; j++) printf("%2d", A[i][j]); printf("\n"); } } int zadacha1(int n, int **A) { int i, j, kk, pp; //kk = 0; pp = 0; for (j=0; j<n; j++) { for (i=0; i<n; i++) if (A[i][j]==0) pp=1; if (pp==0) kk++; } printf("Kolichestvo stolbcov bez 0=%d",kk); } int zadacha2(int n, int **A) { int i, j, k, p, q, r; for (j = 0; j < n; j++) { k = p = 0; for (j = 0; j < n - 1; j++) if (A[i][j] <= A[i][j + 1]) k++; else p++; for (j = 0; j < n; ++j) { for (i = 0; i < n - 1; ++i) { if (A[i][j] > A[i + 1][j]) { r = A[i][j]; A[i][j] = A[i + 1][j]; A[i + 1][j] = r; q = i; } while (A[q][j] < A[q - 1][j] && q > 0) { r = A[q][j]; A[q][j] = A[q - 1][j]; A[q - 1][j] = r; q = q - 1; } } } } } int main() { int n, **A = 0, kol = 5, nom, i; long proizved; char*nazv[] = {"Vvod", "Vivod", "Kolichestvo stolbcov, ne soderjashix ni 1 nulevogo elementa", "Sortirovka matrici metodom proseivaniya", "Exit"}; while(1) { nom = menu(kol, nazv); switch(nom) { case 1: vvod(&n, &A); break; case 2: system("cls"); if (A != NULL) vivod(n, A); else printf("Vvedite matricu!"); getch(); break; case 3: system("cls"); if (A != NULL) { vivod(n, A); zadacha1(n, A); } else printf("Vvedite matricu!"); getch(); break; case 4: system("cls"); if (A != NULL) { vivod(n,A); zadacha2(n, A); printf("\n\n"); vivod(n, A); } else printf("Vvedite matricu!"); getch(); break; case 5: return 0; for(i = 0; i < n; i++) free(A[i]); free(A); } } } |
Сообщ.
#2
,
|
|
|
1. В функции vvod вы в scanf кидаете значение n, а надо - адрес (место, куда запишется размерность)!
2. В функциях vivod, zadacha1 и zadacha2 компилятор не знает размерность матрицы, а потому обеспечить столь желаемое A[k][j] не сможет правильно. 3. В функции zadacha1 переменная kk не инициализируется. Несколько опасно сие. "pp=0" надо внести внутрь первого for'а. Добавлено Ой, виноват: второй пункт замечаний отменяется! Добавлено 2. В функции vvod надо заменить (видимо) на: "void vvod(int *n,", а в выделении памяти и в циклах там использовать (*n). |
Сообщ.
#3
,
|
|
|
Я вроде бы всё исправил, что вы сказали, теперь после ввода размерности матрицы вылетает из программы:
#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <malloc.h> int menu(int kp, char*NAZ[]); int main(void); void vvod(int *n, int ***A); void vivod(int n, int **A); int zadacha1(int n, int kk, int pp, int **A); int zadacha2(int n, int **A); int menu(int kp, char*NAZ[]) { int k, i; for (i = 0; i < kp; i++) printf("\n %d %s", i + 1, NAZ[i]); printf("\n\n Viberite punct menu ->"); scanf("%d",&k); return k; } void vvod(int *n, int ***D) { int i, j; printf("Vvedite razmernost matrici n="); scanf("%d", &n); if (*D != NULL) free(*D); int **A = (int **) malloc (*n * sizeof (int *)); for (i = 0; i < *n; i++) A[i] = (int *) malloc(*n * sizeof (int)); for (i = 0; i < *n; i++) for (j = 0; j < *n; j++) { printf("A[%d][%d]=", i,j); scanf("%d", &A[i][j]); } *D = A; } void vivod(int n, int **A) { int i,j; for (i = 0; i < n; i++) { for (j = 0; j < n; j++) printf("%2d", A[i][j]); printf("\n"); } } int zadacha1(int n, int **A) { int i, j, kk, pp; kk = 0; //pp = 0; for (j=0; j<n; j++) { pp = 0; for (i=0; i<n; i++) if (A[i][j]==0) pp=1; if (pp==0) kk++; } printf("Kolichestvo stolbcov bez 0=%d",kk); } int zadacha2(int n, int **A) { int i, j, k, p, q, r; for (j = 0; j < n; j++) { k = p = 0; for (j = 0; j < n - 1; j++) if (A[i][j] <= A[i][j + 1]) k++; else p++; for (j = 0; j < n; ++j) { for (i = 0; i < n - 1; ++i) { if (A[i][j] > A[i + 1][j]) { r = A[i][j]; A[i][j] = A[i + 1][j]; A[i + 1][j] = r; q = i; } while (A[q][j] < A[q - 1][j] && q > 0) { r = A[q][j]; A[q][j] = A[q - 1][j]; A[q - 1][j] = r; q = q - 1; } } } } } int main() { int n, **A = 0, kol = 5, nom, i; long proizved; char*nazv[] = {"Vvod", "Vivod", "Kolichestvo stolbcov, ne soderjashix ni 1 nulevogo elementa", "Sortirovka matrici metodom proseivaniya", "Exit"}; while(1) { nom = menu(kol, nazv); switch(nom) { case 1: vvod(&n, &A); break; case 2: system("cls"); if (A != NULL) vivod(n, A); else printf("Vvedite matricu!"); getch(); break; case 3: system("cls"); if (A != NULL) { vivod(n, A); zadacha1(n, A); } else printf("Vvedite matricu!"); getch(); break; case 4: system("cls"); if (A != NULL) { vivod(n,A); zadacha2(n, A); printf("\n\n"); vivod(n, A); } else printf("Vvedite matricu!"); getch(); break; case 5: return 0; for(i = 0; i < n; i++) free(A[i]); free(A); } } } |
Сообщ.
#4
,
|
|
|
void vvod(int n, int ***D) { int i, j; int** A; printf("Vvedite razmernost matrici n="); scanf("%d", &n); if (*D != NULL) free(*D); A = (int **) malloc (n * sizeof (int *)); for (i = 0; i < n; i++) A[i] = (int *) malloc(n * sizeof (int)); for (i = 0; i < n; i++) for (j = 0; j < n; j++) { printf("A[%d][%d]=", i,j); scanf("%d", &A[i][j]); } *D = A; } 1. зачем юзать транслитерацию, когда можно заюзать setlocale с руссификацией всех диалогов 2. слабейшие названия переменных (аля x, y, n, f etc) 3. не понимаю и никогда не понимал, зачем записывать больше одного оператора в 1-й строке (в отладчике потом запаришься) Добавлено 4. комплияция на чистом СИ (анси 89) не пройдет твоей прожки! есть 1-а ошибка..(хинт: объявление А!) |
Сообщ.
#5
,
|
|
|
Цитата FasterHarder @ Пройдёт. Это такое же описание указателя на указатель на целое, как и у тебя. У него в функции vvod ошибка с освобождением D, происходит утечка памяти, так как он массивы второго уровня не освобождает. 4. комплияция на чистом СИ (анси 89) не пройдет твоей прожки! есть 1-а ошибка..(хинт: объявление А!) |
Сообщ.
#6
,
|
|
|
Цитата amk @ Пройдёт не пройдет проверял посмотри ф-цию vvod, переменная A объявляется НИЖЕ операторов printf/scanf - по стандарту ANSI C это недопустимо |
Сообщ.
#7
,
|
|
|
Andrey_2019, вы переправили чуть больше, чем надо было! В функции vvod у вас уже посылается адрес n(входной парам.), поэтому при scanf'е не надо снова брать адрес, надо просто n отдать (это ж адрес!).
|
Сообщ.
#8
,
|
|
|
Всё, я уже починил эту программу. Всем огромное спасибо, кто помогал. Вот мой код, если кому нужно:
#include <stdio.h> #include <stdlib.h> #include <conio.h> #include <malloc.h> int menu(int count, char* menu[]) { int k; for (int i = 0; i < count; i++) printf("\n %d %s", i + 1, menu[i]); printf("\n\n Viberite punct menu ->"); scanf("%d",&k); return k; } void vvod(int *n, int ***D) { printf("Vvedite razmernost matrici n="); scanf("%d", n); if (*D != NULL) free(*D); int **A = (int **) malloc (*n * sizeof (int *)); for (int i = 0; i < *n; i++) A[i] = (int *) malloc(*n * sizeof (int)); for (int i = 0; i < *n; i++) for (int j = 0; j < *n; j++) { printf("A[%d][%d]=", i,j); scanf("%d", &A[i][j]); } *D = A; } void vivod(int n, int **A) { for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) printf("%2d", A[i][j]); printf("\n"); } } int zadacha1(int n, int **A) { int kk, pp; kk = 0; for (int j = 0; j < n; j++) { pp = 0; for (int i = 0; i < n; i++) if (A[i][j] == 0) { pp = 1; break; } if (pp == 0) kk++; } printf("Kolichestvo stolbcov bez 0=%d",kk); } int zadacha2(int n, int **A) { int q, swapper; for (int i = 0; i < n; i++) for (int j = 0; j < n - 1; j++) if (A[j][i] > A[j + 1][i]) { swapper = A[j][i]; A[j][i] = A[j + 1][i]; A[j + 1][i] = swapper; if (j == 0) continue; q = j; while (A[q][i] < A[q-1][i]) { swapper = A[q][i]; A[q][i] = A[q-1][i]; A[q-1][i] = swapper; if (q-- == 1) break; } } } int main() { int kol = 5; int n, **A = 0, nom, i; long proizved; char* mainMenu[] = { "Vvod", "Vivod", "Kolichestvo stolbcov, ne soderjashix ni 1 nulevogo elementa", "Sortirovka matrici metodom proseivaniya", "Exit"}; while(1) { nom = menu(kol, mainMenu); switch(nom) { case 1: vvod(&n, &A); break; case 2: system("cls"); if (A != NULL) vivod(n, A); else printf("Vvedite matricu!"); getch(); break; case 3: system("cls"); if (A != NULL) { vivod(n, A); zadacha1(n, A); } else printf("Vvedite matricu!"); getch(); break; case 4: system("cls"); if (A != NULL) { vivod(n, A); zadacha2(n, A); printf("\n\n"); vivod(n, A); } else printf("Vvedite matricu!"); getch(); break; case 5: return 0; for(i = 0; i < n; i++) free(A[i]); free(A); } } } |
Сообщ.
#9
,
|
|
|
Цитата FasterHarder @ Точно, отвык уже (уточнение: printf и scanf не операторы, а вызовы функций, а вот следующий за ними if - оператор). Правда об этом компилятор сообщит. А утечка памяти пройдёт незамеченной. переменная A объявляется НИЖЕ операторов printf/scanf |