Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 07.02.2012, 20:57   #1
Андрей!
Пользователь
 
Регистрация: 04.11.2011
Сообщений: 45
Восклицание Массив указателей, динамическое выделение памяти

Поменять местами первую строчку матрицы и первую строчку с нулевым элементом

собственно написал код:
Код:
#include<locale.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

void razmer(int &, int &, int);
void vvod(double**, int, int, int);
void vivod(double**, int, int, int);
void find_0(double**, int, int, int &);
void swap(double**, int, int, int);
void mclear(double** , int);

int main()
{
   setlocale(LC_ALL,"Rus");
   double **a, **b;
   int i_A, j_A, i_B, j_B;
   int i, num;
   int min_A, min_B;
//Ввод и выделение памяти. Матрица 1
   razmer(i_A, j_A, 1);
//выделение памяти   
   a=(double**)malloc(i_A*sizeof(double));
   for(i=0;i<j_A;i++)
      {
         a[i]=(double*)malloc(j_A*sizeof(double));
      }
   
   vvod(a, i_A, j_A, 1);
   printf("\nИсходная ");
   vivod(a, i_A, j_A, 1);
   find_0(a, i_A, j_A, min_A);
   printf("min_A = %d\n", min_A); 
   //swap(a, i_A, j_A, min_A);
   printf("Новая ");
   vivod(a, i_A, j_A, 1);
   /*  
   razmer(i_B, j_B, 2);
   b=(double**)malloc(i_B*sizeof(double));
   for(i=0;i<j_B;i++)
      {
         b[i]=(double*)malloc(j_B*sizeof(double));
      }
   
   vvod(b, i_B, j_B, 2);
   printf("\nИсходная ");
   vivod(b, i_B, j_B, 2);
   find_0(b, i_B, j_B, min_B);
   swap(b, i_B, j_B, min_B);
   printf("Новая ");
   vivod(b, i_B, j_B, 2);
   */
 //освобождение памяти  
   //mclear(a, i_A);
  //mclear(b, i_B);
   printf("\nПамять очищена!\n");
   getch();
}

void razmer(int &m, int &n, int num)
      {
         printf("\nРазмер матрицы  %d:\n", num);
         printf("строки = ");
            scanf("%d", &m);
         printf("столбцы = ");
            scanf("%d", &n);
      }

void vvod(double** arr, int m, int n, int num)
   {
      int i=0, j=0;
      printf("\nВведите элементы матрицы %d:\n", num);
      for(i=0;i<m;i++)
         for(j=0;j<n;j++)
            {
               printf("   строка %d столбец %d = ", i+1, j+1);
               scanf("%lf", &arr[i][j]);
            }
   }

void vivod(double** arr, int m, int n, int num)
{
        printf("Матрица %d:\n", num);
        for(int i=0; i<m; i++)
        {
                for(int j=0; j<n; j++) 
                   printf("%  5.3lf", arr[i][j]); 
                printf("\n"); 
        } 
}

void find_0(double** arr, int m, int n, int &min)
   {
      for(int i=0;i<m;i++)
         for(int j=0;j<n;j++)
         {
            if(min==-1)
            {
               if(arr[i][j]==0)
                  {
                      min=i;
                  }
               else
                  if(min!=-1)break;       
            }
         
         }
   }

void swap(double** arr, int m, int n, int min)
   {
   int i,j;
   double c;
      {
      for (j=0;j<n;j++)
         {
	 	    c=arr[0][j];
            arr[0][j]=arr[min][j];
            arr[min][j]=c;
	     }
      }
    }

void mclear(double** arr, int n)
{
    for(int i=0; i<n; i++)
       free(arr[i]);
    free(arr);
}
Знаю что сделал по убогому, но хочу этот вариант добить. Точнее надо его добить. Всё ок работало но я что-то накурочил... Все функции - работают хорошо, проблема в том - что функция свап не работает. Точнее find_0. Она ВРОДЕ БЫ неправильно находит первую строчку с нулевым элементом. (Сделал принтф min_A - пишет рандомные числа)

Подскажите пожалуйста как можно исправить! Спасибо!
Андрей! вне форума Ответить с цитированием
Старый 07.02.2012, 21:00   #2
Андрей!
Пользователь
 
Регистрация: 04.11.2011
Сообщений: 45
По умолчанию

если что - swap специально закоментил)

а вторую матрицу - просто убрал пока что, чтобы восстановить работоспособность кода в целом
Андрей! вне форума Ответить с цитированием
Старый 07.02.2012, 23:26   #3
Андрей!
Пользователь
 
Регистрация: 04.11.2011
Сообщений: 45
По умолчанию

Код:
#include<locale.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

void razmer(int &, int &, int);
void vvod(double**, int, int, int);
void vivod(double**, int, int, int);
void find_0(double**, int, int, int &);
void swap(double**, int, int, int &);
void mclear(double** , int);

int main()
{
   setlocale(LC_ALL,"Rus");
   double **a, **b;
   int i_A, j_A, i_B, j_B;
   int i, num;
   int min_A, min_B;
//Ввод и выделение памяти. Матрица 1
   razmer(i_A, j_A, 1);
//выделение памяти   
   a=(double**)malloc(i_A+sizeof(double));
   for(i=0;i<j_A;i++)
      {
         a[i]=(double*)malloc(j_A*sizeof(double));
      }
   
   vvod(a, i_A, j_A, 1);
   printf("\nИсходная ");
   vivod(a, i_A, j_A, 1);
   find_0(a, i_A, j_A, min_A);
   printf("\nmin_A = %d\n", min_A); 
   swap(a, i_A, j_A, min_A);
   printf("Новая ");
   vivod(a, i_A, j_A, 1);
   
   razmer(i_B, j_B, 2);
   b=(double**)malloc(i_B*sizeof(double));
   for(i=0;i<j_B;i++)
      {
         b[i]=(double*)malloc(j_B*sizeof(double));
      }
   
   vvod(b, i_B, j_B, 2);
   printf("\nИсходная ");
   vivod(b, i_B, j_B, 2);
   find_0(b, i_B, j_B, min_B);
   printf("\bmin_B=%d\n", min_B);
   swap(b, i_B, j_B, min_B);
   printf("Новая ");
   vivod(b, i_B, j_B, 2);
  
 //освобождение памяти  
   mclear(a, i_A);
   mclear(b, i_B);
   printf("\nПамять очищена!\n");
   getch();
}

void razmer(int &m, int &n, int num)
      {
         printf("\nРазмер матрицы  %d:\n", num);
         printf("строки = ");
            scanf("%d", &m);
         printf("столбцы = ");
            scanf("%d", &n);
      }

void vvod(double** arr, int m, int n, int num)
   {
      int i=0, j=0;
      printf("\nВведите элементы матрицы %d:\n", num);
      for(i=0;i<m;i++)
         for(j=0;j<n;j++)
            {
               printf("   строка %d столбец %d = ", i+1, j+1);
               scanf("%lf", &arr[i][j]);
            }
   }

void vivod(double** arr, int m, int n, int num)
{
        printf("Матрица %d:\n", num);
        for(int i=0; i<m; i++)
        {
                for(int j=0; j<n; j++) 
                   printf("%  5.3lf", arr[i][j]); 
                printf("\n"); 
        } 
}

void find_0(double** arr, int m, int n, int &min)
{
int flag=1,i,j;
for(i=0;i<m&&amp;flag;i++)
for(j=0;j<n&&amp;flag;j++)
if(arr[i][j]==0)
{
flag=0;
min=i;
}
if(flag)
min=-1;
}

void swap(double** arr, int m, int n, int &min)
{
int i,j;
double c;
if(min!=-1)
{
for (j=0;j<n;j++)
{
c=arr[0][j];
arr[0][j]=arr[min][j];
arr[min][j]=c;
}
}
}

void mclear(double** arr, int n)
{
    for(int i=0; i<n; i++)
       free(arr[i]);
    free(arr);
}
Исправил программу. Но она отказывается работать если строк больше чем столбцов. Скорее всего неправильно выделяю память. Подскажите пожалуйста

Последний раз редактировалось Андрей!; 07.02.2012 в 23:34.
Андрей! вне форума Ответить с цитированием
Старый 08.02.2012, 01:37   #4
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Цитата:
Сообщение от Андрей! Посмотреть сообщение
Код:
void find_0(double** arr, int m, int n, int &min)
{
int flag=1,i,j;
for(i=0;i<m&&amp;flag;i++)
for(j=0;j<n&&amp;flag;j++)
if(arr[i][j]==0)
{
flag=0;
min=i;
}
if(flag)
min=-1;
}
Исправил программу. Но она отказывается работать если строк больше чем столбцов. Скорее всего неправильно выделяю память. Подскажите пожалуйста

Я смотрю на код вашей функции find_0 и понять не могу, что эта за переменная amp, и как вообще может работать такая конструкция

for(i=0;i<m&&amp;flag;i++) ???

Сложность кода - это источник ошибок. Насколько я понял, вам надо найти строку в матрице, которая содержит нулевой элемент. Так и напишите функцию, которая ищет нулевой элемент в строке, то есть в одномерном массиве, а не передавайте всю матрицу в функцию.
Со мной можно встретиться на www.clipper.borda.ru
Сыроежка вне форума Ответить с цитированием
Старый 08.02.2012, 01:40   #5
Андрей!
Пользователь
 
Регистрация: 04.11.2011
Сообщений: 45
По умолчанию

Цитата:
Сообщение от Сыроежка Посмотреть сообщение
Я смотрю на код вашей функции find_0 и понять не могу, что эта за переменная amp, и как вообще может работать такая конструкция

for(i=0;i<m&&amp;flag;i++) ???

Сложность кода - это источник ошибок. Насколько я понял, вам надо найти строку в матрице, которая содержит нулевой элемент. Так и напишите функцию, которая ищет нулевой элемент в строке, то есть в одномерном массиве, а не передавайте всю матрицу в функцию.
ну я не придумал другого способа(
просто мне нужно заставить её работать именно таким способом (по заданию) а я болел эту тему, вот и не могу понять
Андрей! вне форума Ответить с цитированием
Старый 08.02.2012, 02:03   #6
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Цитата:
Сообщение от Андрей! Посмотреть сообщение
ну я не придумал другого способа(
просто мне нужно заставить её работать именно таким способом (по заданию) а я болел эту тему, вот и не могу понять
Так вы не ответили, что эта за переменная, то есть где она определена, а также, как может компилироваться этот цикл?

Как я уже вам сказал, вам надо написать функцию более простую, которая в строке, который представляет из себя одномерный массив, ищет элемент с заданным значением.

Объявление функции будет выглядеть просто:

bool any_of( int *a, int n, int value );

То есть вам надо устроить один цикл внутри тела этой функции, и если в строке элемент с заданным значением найден, возвращать true, в противном случае - false. То есть вас на самом деле должен волновать не сам конкретный элемент, значение которого равно 0, а сам факт, что в строке есть по крайней мере один элемент с нулевым значением.

Я вам напишу эту функцию, а вы попробуйте самостоятельно ее использовать в своей программе.

Код:
bool any_of( int *a, int n, int value )
{
   int i = 0;

   for (  ; i < n && a[i] != value ; i++ );

   return ( i != n );
}
Попробуйте самостоятельно понять, как работает функция. В качестве значения аргумента для параметра value в вашем случае будет передаваться 0. Если я правильно понял задание, вам просто нужно первую строку матрицы поменять местами со строкой, в которой найден по крайней мере один нулевой элемент. Так?
Со мной можно встретиться на www.clipper.borda.ru

Последний раз редактировалось Сыроежка; 08.02.2012 в 02:14.
Сыроежка вне форума Ответить с цитированием
Старый 08.02.2012, 03:07   #7
Андрей!
Пользователь
 
Регистрация: 04.11.2011
Сообщений: 45
По умолчанию

Цитата:
Сообщение от Сыроежка Посмотреть сообщение
Так вы не ответили, что эта за переменная, то есть где она определена, а также, как может компилироваться этот цикл?

Как я уже вам сказал, вам надо написать функцию более простую, которая в строке, который представляет из себя одномерный массив, ищет элемент с заданным значением.

Объявление функции будет выглядеть просто:

bool any_of( int *a, int n, int value );

То есть вам надо устроить один цикл внутри тела этой функции, и если в строке элемент с заданным значением найден, возвращать true, в противном случае - false. То есть вас на самом деле должен волновать не сам конкретный элемент, значение которого равно 0, а сам факт, что в строке есть по крайней мере один элемент с нулевым значением.

Я вам напишу эту функцию, а вы попробуйте самостоятельно ее использовать в своей программе.

Код:
bool any_of( int *a, int n, int value )
{
   int i = 0;

   for (  ; i < n && a[i] != value ; i++ );

   return ( i != n );
}
Попробуйте самостоятельно понять, как работает функция. В качестве значения аргумента для параметра value в вашем случае будет передаваться 0. Если я правильно понял задание, вам просто нужно первую строку матрицы поменять местами со строкой, в которой найден по крайней мере один нулевой элемент. Так?
да так, просто я проболел много и самостоятельно всё делаю, в инете нарываю материал

сейчас скажу что за переменная
Андрей! вне форума Ответить с цитированием
Старый 08.02.2012, 03:09   #8
Андрей!
Пользователь
 
Регистрация: 04.11.2011
Сообщений: 45
По умолчанию

Код:
void find_0(double** arr, int m, int n, int &min)
{
int flag=1,i,j;
for(i=0;i<m&&amp;flag;i++)
for(j=0;j<n&&amp;flag;j++)
if(arr[i][j]==0)
{
flag=0;
min=i;
}
if(flag)
min=-1;
}
ну в этом цикле я думал так сделать - передаю матрицу, ищу первый нулевой элемент. Если он найден то flag=0 => циклы не выполняются, т.к. остальные нули уже не интересны. flag приравнивается к 0, а значение минимума(строка с первым нулевым элементом = i) (min=i)

я просто не понимаю почему не работает программа когда строчек больше чем столбцов

Последний раз редактировалось ACE Valery; 13.02.2012 в 18:01.
Андрей! вне форума Ответить с цитированием
Старый 08.02.2012, 04:52   #9
Сыроежка
Форумчанин
 
Регистрация: 01.07.2011
Сообщений: 423
По умолчанию

Цитата:
Сообщение от Андрей! Посмотреть сообщение
void find_0(double** arr, int m, int n, int &min)
{
int flag=1,i,j;
for(i=0;i<m&&flag;i++)
for(j=0;j<n&&flag;j++)
if(arr[i][j]==0)
{
flag=0;
min=i;
}
if(flag)
min=-1;
}

ну в этом цикле я думал так сделать - передаю матрицу, ищу первый нулевой элемент. Если он найден то flag=0 => циклы не выполняются, т.к. остальные нули уже не интересны. flag приравнивается к 0, а значение минимума(строка с первым нулевым элементом = i) (min=i)

я просто не понимаю почему не работает программа когда строчек больше чем столбцов
Лучше делать так. как я предложил, так как это более ясный и прозрачный дизайн, когда задача разбивается на простые и понятные функции.
Данную вашу функцию можно написать также проще и понятнее. Виесто значения void, которое не несет никакой информации пользователю функции, лучше возвращать индекс найденной строки или -1, как это делается у вас. Тогда функция будет выглядеть следующим образом

Код:
int find_zero( double **a, int m, int n )
{
   for ( int i = 0; i < m; i++ )
   {
      for ( int j = 0; j < n; j++ )
      {
         if ( a[i][j] == 0 ) return ( i );
      }
   }

   return ( -1 );
}
Цитата:
Сообщение от Андрей! Посмотреть сообщение
[CODE]void swap(double** arr, int m, int n, int &min)
{
int i,j;
double c;
if(min!=-1)
{
for (j=0;j<n;j++)
{
c=arr[0][j];
arr[0][j]=arr[min][j];
arr[min][j]=c;
}
}
}
Также и вашу функцию swap можно упростить. Она у вас имеет лишний параметр m, который нигде внутри нее не используется. Да и проверку на то, что переданный индекс строки не равен -1, надо делать не в самой функции, а в том коде, который ее вызывает.
Передавать же в функцию надо две строки и размер строки.

То есть функция будет выглядеть следующим образом:

Код:
void swap( double *first, double *second, int n )
{
   for ( int i = 0; i < n; i++ )
   {
      double tmp = first[i];
      first[i] = second[i];
      second[i] = tmp;
   }
}
Никаких проверок в ней не делается и нет лишних не используемых параметров.

В основном коде при ее вызове вы просто передаете первую строку, как arr[0], и найденную строку, как arr[x], где x - это найденный индекс строки. То есть код вызова будет выглядеть следующим образом

Код:
int row = find_zero(arr, m, n );
if ( 0 < row ) swap( arr[0], arr[row], n );
Как видите, все просто.

И при выделении памяти у вас ошибка. То есть данное предложение

a=(double**)malloc(i_A+sizeof(doubl e));

не корректно. Вы на самом деле должны выделить память под массив указателей на double. И кроме того в выражении для аргумента должна быть не сумма, а произведение количества строк, то есть i_A на размер выделяемого объекта.

Поэтому должно быть

a = ( double ** )malloc( i_A * sizeof( double *) );

Так что это была у вас серьезная ошибка в программе.
Со мной можно встретиться на www.clipper.borda.ru

Последний раз редактировалось Stilet; 08.02.2012 в 22:40.
Сыроежка вне форума Ответить с цитированием
Старый 08.02.2012, 20:35   #10
Андрей!
Пользователь
 
Регистрация: 04.11.2011
Сообщений: 45
По умолчанию

Слушай, я исправил ошибку (глупая на самом деле)

Программа ок компилируется, но также работает некорректно, если в исходные данные ввести строк больше чем столбцов

Вот код:

Код:
#include<locale.h>
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>

void razmer(int &, int &, int);
void vvod(double**, int, int, int);
void vivod(double**, int, int, int);
void find_0(double**, int, int, int &);
void swap(double**, int, int, int &);
void mclear(double** , int);

int main()
{
   setlocale(LC_ALL,"Rus");
   double **a, **b;
   int i_A, j_A, i_B, j_B;
   int i, num;
   int min_A, min_B;
//Ввод и выделение памяти. Матрица 1
   razmer(i_A, j_A, 1);
//выделение памяти   
   a = ( double ** )malloc( i_A * sizeof( double *) );
   for(i=0;i<j_A;i++)
      {
         a[i]=(double*)malloc(j_A*sizeof(double));
      }
   
   vvod(a, i_A, j_A, 1);
   printf("\nИсходная ");
   vivod(a, i_A, j_A, 1);
   find_0(a, i_A, j_A, min_A);
   printf("\nmin_A = %d\n", min_A); 
   swap(a, i_A, j_A, min_A);
   printf("Новая ");
   vivod(a, i_A, j_A, 1);
   
   razmer(i_B, j_B, 2);
   b = ( double ** )malloc( i_B * sizeof( double *) );
   for(i=0;i<j_B;i++)
      {
         b[i]=(double*)malloc(j_B*sizeof(double));
      }
   
   vvod(b, i_B, j_B, 2);
   printf("\nИсходная ");
   vivod(b, i_B, j_B, 2);
   find_0(b, i_B, j_B, min_B);
   printf("\bmin_B=%d\n", min_B);
   swap(b, i_B, j_B, min_B);
   printf("Новая ");
   vivod(b, i_B, j_B, 2);
  
 //освобождение памяти  
   mclear(a, i_A);
   mclear(b, i_B);
   printf("\nПамять очищена!\n");
   getch();
}

void razmer(int &m, int &n, int num)
      {
         printf("\nРазмер матрицы  %d:\n", num);
         printf("строки = ");
            scanf("%d", &m);
         printf("столбцы = ");
            scanf("%d", &n);
      }

void vvod(double** arr, int m, int n, int num)
   {
      int i=0, j=0;
      printf("\nВведите элементы матрицы %d:\n", num);
      for(i=0;i<m;i++)
         for(j=0;j<n;j++)
            {
               printf("   строка %d столбец %d = ", i+1, j+1);
               scanf("%lf", &arr[i][j]);
            }
   }

void vivod(double** arr, int m, int n, int num)
{
        printf("Матрица %d:\n", num);
        for(int i=0; i<m; i++)
        {
                for(int j=0; j<n; j++) 
                   printf("%  5.3lf", arr[i][j]); 
                printf("\n"); 
        } 
}

void find_0(double** arr, int m, int n, int &min)
{
int flag=1,i,j;
for(i=0;i<m&&flag;i++)
for(j=0;j<n&&flag;j++)
if(arr[i][j]==0)
{
flag=0;
min=i;
}
if(flag)
min=-1;
}

void swap(double** arr, int m, int n, int &min)
{
int i,j;
double c;
if(min!=-1)
{
for (j=0;j<n;j++)
{
c=arr[0][j];
arr[0][j]=arr[min][j];
arr[min][j]=c;
}
}
}

void mclear(double** arr, int n)
{
    for(int i=0; i<n; i++)
       free(arr[i]);
    free(arr);
}
Андрей! вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Динамическое выделение памяти , realloc. _-Re@l-_ Общие вопросы C/C++ 8 03.11.2011 10:20
Выделение памяти под массив указателей Анка291 Общие вопросы C/C++ 9 25.02.2011 00:03
Динамическое выделение памяти, как лучше? Пепел Феникса Общие вопросы по программированию, компьютерный форум 10 11.03.2010 09:44
Динамическое выделение памяти под массив объектов со специализированным конструктором capta1n Общие вопросы C/C++ 6 07.03.2010 16:01
Динамическое выделение памяти FW-TOT Общие вопросы C/C++ 2 19.12.2008 00:42