Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Двумерный массив. Совпадение строки и столбца, и сумма строки с отрицательным элементом 
V
    Опции темы
voral
Дата 27.12.2011, 13:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 16.3.2008
Где: Иваново

Репутация: нет
Всего: нет



Цитата(krot100500 @  27.12.2011,  12:58 Найти цитируемый пост)
ну вообщем функция void input -вводит массив, взят текс тупо из методички
void subzero -функция нахождение элемента ниже 0 и сумма всех элементов этой строки
void out функция тоже взята из методы ) выводит массив заданый в inpute

Что ожидалось от этих функций я догадался. Но беда в том, что только в функции comp и subzero может попасть массив из-вне. В main, input и out переменные, ссылающиеся на массив, хоть и называются одинаково. Тем не менее это совершенно разные переменные. И только в input эта переменная ссылается на выделенный кусок памяти. В остальных случаях идет обращение к мусору и как результат сегфолт.
Почитай внимательно по ключевой фразе "область видимости".

Цитата(krot100500 @  27.12.2011,  12:58 Найти цитируемый пост)
в исходники из методички я особо не разбирался просто коррекция под свой вариант) динамическое распределение памяти для меня лес темный(( примерно понял операнд малок( по Герберту Шилдту)

В твоем коде по сути нет ошибок с "выделением динамической памяти" как таковым. Основные ошибки:
1 непонимание области видимости переменных
2. расстановка точки с запятой где ни попадя. Пример:
Код

for (int i=0; i < 4; ++i);
{
      printf ("first\n");
}

for (int i=0; i < 4; ++i)
{
      printf ("second\n");
}

В результате этого кода будет выведено 1 раз слово "first" и 4 раза слово "second"

В итоге в input у тебя выделяется память под массив массивов. И один раз (вместо 3) для массива.



Цитата(krot100500 @  27.12.2011,  12:58 Найти цитируемый пост)
ЗЫ Voral свой код всегда узнать можно)) я взял твой код для статического распределения попытался в нем разобраться) вроде как понял что-то) непонял тока почему цикл тока для J есть (в comparline)

Да нашел. Эта функция вызывается из цикла по i. А i передается в функцию в качестве параметра.


PM MAIL WWW   Вверх
krot100500
Дата 27.12.2011, 22:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 26.12.2011

Репутация: нет
Всего: нет



т.е как я понял для того чтобы функция "работала с массивом a[i][j]", к примеру, subzero должна иметь параметр не (int i), а (int a) и соответственo нужно вводить 2-й for?
PM MAIL   Вверх
voral
Дата 27.12.2011, 23:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 16.3.2008
Где: Иваново

Репутация: нет
Всего: нет



Как раз subziro у тебя все правильно принимает в качестве параметра указатель на массив массивов переданный из функции main. Беда в том, что в ф-ии main переменная а ни на чего не указывает. Короче вот почти твой код с коментариями. У меня не винда, так что не прверял виндозависимые строки, но дожно быть все ок.

Код

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <alloc.h>
#define SIZE 3
int** input()
{
    // в этой функции я возвращаю адрес массива массивов в памяти
    // в нее ни чего не передается, но она передает информацию во внешний блок

    // эта переменная ни чем не связана с mainArray в ф-ии main
    // ее можно назвать как угодно в том числе и mainArray - это ни чего
    // не изменит. Она существует только внутри input()
    int **a; 
    int i,j;
    // выделяем память под массив указателей на массивы
    a=(int**)malloc(SIZE*sizeof(int*)); 
    // в конце следующей строки нет ни какой ; иначе блок в последующих скобках
    // не будет иметь ни какого отношения к for
    for(i=0; i<SIZE; ++i)   
    {
        // выделяем память под масиив типа int
        // обрати внимание размер типа int, а не размер ссылки на тип int
        // как в твоем код
        a[i]=(int*)malloc(SIZE*sizeof(int));
    }
    printf("vvedite element matrici\n");
    for(i=0; i<SIZE; ++i)
    {
        for(j=0; j<SIZE; ++j)
        {
            printf("a[%d][%d]=",i,j);
            scanf("%d",&a[i][j]);
        }
    }
    return a; // возвращаем в вызвавший код адрес нашего массива
}
void out(int **a)
{
    int i,j;
    printf("matrica\n");
    for(i=0; i<SIZE; ++i)
    {
        for(j=0; j<SIZE; ++j)
            printf("%8d",a[i][j]);
        printf("\n");
    }
}
int main()

    clrscr();
    // здесь для наглядности меняю имя
    // объявляем переменную и сразу инициализируем ее значением
    // получаемым из ф-ии input 
    // если не делать присвоения. То с выходом из input
    // тамошняя переменная a перестанет существовать и мы забудем
    // где в памяти находится наш массив
    int **mainArray = input(); 
    
    //Чтобы out знала о нашем массиве передаем в качестве параметра
    out(mainArray);
    
    //очищаем память
    int i;
    for(i=0; i<SIZE; ++i)
    {
        free(mainArray[i]);
    }
    free(mainArray);
    getch();
    return 0;
}


Это сообщение отредактировал(а) voral - 27.12.2011, 23:36
PM MAIL WWW   Вверх
krot100500
Дата 28.12.2011, 21:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 26.12.2011

Репутация: нет
Всего: нет



Код

int main()

     clrscr();
     int **mainArray = input(); 
     out(mainArray);  
    int i;
    for(i=0; i<SIZE; ++i)
    {
        free(mainArray[i]);
    }
    free(mainArray);
    getch();
    return 0;
}


как я понял строка 3 вводит указатель mainArray и присваевает ему значение input(который сам по-сути является именем-указателем функции) 
строка 4 придает функции out параметр mainArroy, и благодаря этому функция out будут работать как-бы с массивом из input
а вот дальше чуток уже напряжка)
с момента инициальзации i;
мы получается освобождаем память от mainArroy или от input на которую она и является указателем?

PM MAIL   Вверх
krot100500
Дата 28.12.2011, 22:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 26.12.2011

Репутация: нет
Всего: нет



Чуть не забыл: чтобы функция к примеру comp работала с моим массивом что нужно сделать? а то написал а он при любых раскладах выдает результат 1 и все*( 
Код

int comp(int i)
{   int **a;
    int j;
    for (j=0;j<SIZE;++j)
       {if (a[i][j]!=a[j][i])
    printf("sovpadeni'a v %d stroke i stolbce\n",i+1);
    else printf("net sovpadeniy\n");}
    return 0;
    }

 как нас учили первые 2 строки должны быть такими:
Код

int comp(int a)
{ int i,j;


Добавлено через 10 минут и 9 секунд
Чуток пораскинув своим упрямым мозгом пришла мысль: 
Код

int **func1 = input();
out(func1);

у нас тут как раз и присваиваются значения?
и чтобы comp работала с моим массивом надо её так-же объявлять?
   

Это сообщение отредактировал(а) krot100500 - 28.12.2011, 22:14
PM MAIL   Вверх
voral
Дата 29.12.2011, 00:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 16.3.2008
Где: Иваново

Репутация: нет
Всего: нет



Передача параметра у вас была правильно сделана в первом варианте ф-ии comp. Ваш второй вариант этой ф-ии говорит о том что вы совершенно не просекли разницы между вашей ф-ией out и моей. К тому же у вас отсутствует цикл по j. В том моем коде в начале топика есть цикл по обоим индексам, хотя в приведенной вами функции только по одному. Но на то были причины. У вас же цикл только по одному индексу. А j может принять, на момент использование, совершенно разное значение, которое зависит "от фазы луны и расположния звезд"....


Вообще, думаю, для вас самый быстрый метод понимание и решения вашей ошибки в этой задаче. Будет внимательное прочтение книги Кернигана и Ритчи "Язык программирования Си" (с первой страницы). У вас проблемы не с указателями и выделением памяти, а в еще более базовых понятиях. Вы слишком спишите. Указатели вам пока рано.

Я б, конечно мог, разжевать данный конкретный пример. Но одно из двух: либо вы все равно ни чего не поняли либо мне бы пришлось почти полностью здесь воспроизвести вышеупомянутую книгу (по крайней мере до указателей)
PM MAIL WWW   Вверх
krot100500
Дата 29.12.2011, 00:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 26.12.2011

Репутация: нет
Всего: нет



Цитата(voral @  29.12.2011,  00:03 Найти цитируемый пост)
К тому же у вас отсутствует цикл по j.

у меня он есть тока в другом ... не в том который скинул*) а спишу ибо застрял с этой задачкой*( это курсовое задание на выполнение которого осталось 1 ночь и 2 дня) бьюсь я с ним уже месяц, прочитал книгу Герберта Шилдта но там слишком непонятно... методичку от нашего препода- там ошибка на ошибке, которые вижу даже я))) что уж говорить о лекциях)
ЗЫ язык си у нас начался совсем недавно) 
для примера мы написали пока-что 4-ре лабы)
1)прога для вывода на экран "привет мир"*)
.
.
.
4)прога для рандомного заполнения масива 5 на 5)
а курсовая работа совершенно другово порядка)
Книгу Кернига скачал вчера пока не читал*печаль*


PM MAIL   Вверх
krot100500
Дата 29.12.2011, 22:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 26.12.2011

Репутация: нет
Всего: нет



Код

#include <stdlib.h>
#include <alloc.h>
#include <conio.h>
#define SIZE 3
int i,j;
int** input(int);
int* comp(int **, int);
int* subzero(int **, int);
int** input(int k)
 {
    int **matr;
    k=SIZE;
    int i,j;
    matr=(int**)malloc(k*sizeof(int*));
    for(i=0; i<k; ++i)
    {
    matr[i]=(int*)malloc(k*sizeof(int));
    }
    printf("vvedite element matrici\n");
    for(i=0; i<k; ++i)
    {
    for(j=0; j<k; ++j)
    {
        printf("a[%d][%d]=",i+1,j+1);
        scanf("%d",&matr[i][j]);
    }
    }
    return matr;
}
int* comp(int **matr,int k)
{   int j,i;
    int *stroka=(int*)malloc(k*sizeof(int));
    k=SIZE; stroka=0;
    for (i=0;i<k;++i)
    {for (j=0;j<k;++j)
       {if (matr[i][j]=matr[j][i])
    stroka=stroka+1;
    else stroka =0;}
    printf("sovpadeni'a v %d stroke i stolbce\n",i+1);}
    return stroka;}
int* subzero(int **matr,int k)
{
    int *sum=(int*)malloc(k*sizeof(int));
    int i,j,fex;
    sum=0;fex=0;k=SIZE;
    for (j=0;j<k;j++)
     {
     sum+=matr[i][j];
     if(matr[i][j]<0) fex=1;
     }
    if (fex==1)
      printf("v stroke %d est' <0; sum=%d\n",i+1,sum);
      return sum;
      }
   main()
      {
      clrscr();
      int **matr;
      int *stroka, *sum;
      int k=SIZE;
      printf("vvedite massiv\n");
      matr=input(k);
      stroka=comp(matr,k);
      sum=subzero(matr,k);
      free(matr);
      free(stroka);
      free(sum);
      getch();
      return 0;}

Прочитал Кернигана(не всего) и вот что получилось

печаль в том что прога вылетает*(
все та-же печаль с указателем
PM MAIL   Вверх
krot100500
Дата 29.12.2011, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 26.12.2011

Репутация: нет
Всего: нет



не тот выкинул*)

PM MAIL   Вверх
voral
Дата 30.12.2011, 01:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 16.3.2008
Где: Иваново

Репутация: нет
Всего: нет



Жесть. У вас stroka - это не переменная типа int!!!   Это указатель. И операция stroka = stroka + 1 означает что вы смещаете укзатедь в памяти
PM MAIL WWW   Вверх
krot100500
Дата 30.12.2011, 02:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 26.12.2011

Репутация: нет
Всего: нет



3-е сутки без сна дают о себе знать) я запустил прогу она брякнулась но не сохранил*((
int main(void)
Код

int main(void)
{
 int i[5];
func(i);
.
.}

вопросик: в func передан индекс массива i?
т.е. если не выходя из блока main я буду использовать func я буду использовать как бы массив i?
или нужно будет делать это так
Код

int*func;
int i[5];
funk=i

а то как то в литературе непонятно) или это бессоница?*)

Это сообщение отредактировал(а) krot100500 - 30.12.2011, 02:48
PM MAIL   Вверх
krot100500
Дата 30.12.2011, 03:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 26.12.2011

Репутация: нет
Всего: нет



Я ВКУРИЛ!!!!!Еххааа Voral СПАСИБИЩЕ!!!)
метод проб и ошибок рулит)))
я заного прочитал все в этом топике и на 10 раз пришла истина*)
Код

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <alloc.h>
#define SIZE 3
int** input()
{
    int **a;
    int i,j;
    a=(int**)malloc(SIZE*sizeof(int*));
    for(i=0; i<SIZE; ++i)
    {
       a[i]=(int*)malloc(SIZE*sizeof(int));
    }
    printf("vvedite element matrici\n");
    for(i=0; i<SIZE; ++i)
    {
    for(j=0; j<SIZE; ++j)
    {
        printf("a[%d][%d]=",i,j);
        scanf("%d",&a[i][j]);
    }
    }
    return a;
}
void comp(int i)
{int j;
 int **a;
 for (j=0;j<SIZE;j++)
  {if (a[i][j]!=a[j][i])return;
   printf("sovpadeni'a v %d stroke i stolbce\n",i+1);
   }}
void sum(int i)
{   int **a;
    int j, suma=0, fex=0;
    for (j=0;j<SIZE;j++)
    {suma+=a[i][j];
     if (a[i][j]<0) fex=1;
    }
    if (fex==1) printf("otricatel'ni element est' v stroke %d summa elementov= %d\n",i+1,suma);
    }
void out(int **a)
{
    int i,j;
    printf("matrica\n");
    for(i=0; i<SIZE; ++i)
    {
    for(j=0; j<SIZE; ++j)
        printf("%8d",a[i][j]);
    printf("\n");
    }
}
int main()
{
    clrscr();
    int **a= input();
    out(a);
    int i;
    for(i=0; i<SIZE; ++i)
    {
      comp(i);
      sum(i);
      free(a[i]);
    }
    free(a);
    getch();
    return 0;
}




Это сообщение отредактировал(а) krot100500 - 30.12.2011, 03:19
PM MAIL   Вверх
krot100500
Дата 30.12.2011, 03:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 26.12.2011

Репутация: нет
Всего: нет



Печаль случилась*((( при увеличении массива до 8Х8 выдает фейловые рез-ты
ошибку не найти*( постинкримент изменил на прединкремент(comp ф-я)
PM MAIL   Вверх
voral
Дата 30.12.2011, 09:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 158
Регистрация: 16.3.2008
Где: Иваново

Репутация: нет
Всего: нет



Если бы вы очень внимательно сравнили свою исходную функцию out и мой вариант. То у вас бы в коде было на две серьезных ошибки меньше. Править не буду, но прокомментирую ваш код:
Код

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <alloc.h>
#define SIZE 3
int** input()
{
    int **a;
    int i,j;
    a=(int**)malloc(SIZE*sizeof(int*));
    for(i=0; i<SIZE; ++i)
    {
        a[i]=(int*)malloc(SIZE*sizeof(int));
    }
    printf("vvedite element matrici\n");
    for(i=0; i<SIZE; ++i)
    {
        for(j=0; j<SIZE; ++j)
        {
            printf("a[%d][%d]=",i,j);
            scanf("%d",&a[i][j]);
        }
    }
    return a;
}
void comp(int i)
{
    int j;
    int **a; // вы обявили массив a
    for (j=0;j<SIZE;j++)
    {
        // теперь работаете с неким массиивом на который ссылатся a
        // беда в том, что локальная переменная a ни как не инициализирована
        // она может равно 0 а может 100500 
        // и ваша программа обращается по этому адресу в памяти, а что по этому адресу не известно
        // программа здесь валится
        // выход: понять почему в out нет в теле функции строки int **a; и сделать по образу и подобию
        // иначе говоря передать в эту функцию адрес уже существующего массива в памяти
        if (a[i][j]!=a[j][i])return;
        printf("sovpadeni'a v %d stroke i stolbce\n",i+1);
    }
}
void sum(int i)
{
    // абсолютно те же самые коментарии что и в comp
    int **a;
    int j, suma=0, fex=0;
    for (j=0;j<SIZE;j++)
    {
        suma+=a[i][j];
        if (a[i][j]<0) fex=1;
    }
    if (fex==1) printf("otricatel'ni element est' v stroke %d summa elementov= %d\n",i+1,suma);
}
void out(int **a)
{
    int i,j;
    printf("matrica\n");
    for(i=0; i<SIZE; ++i)
    {
        for(j=0; j<SIZE; ++j) printf("%8d",a[i][j]);
        printf("\n");
    }
}
int main()
{
    clrscr();
    int **a= input();
    out(a);
    int i;
    for(i=0; i<SIZE; ++i)
    {        
        comp(i);
        sum(i);
        // казалось бы оптимизирующее решение: обработали строку и сразу 
        // в том же самом цикле ее удалили (освободили память занимаеую ею)
        // но допустим вы испраили ошибки в функциях выше по шагам:
        // i=0;  - отрабатывает comp, sum и освобождаем память занятую первой строкой
        // i=1;  - идем в comp:
        //        j=0: if (a[1][0]!=a[0][1])...... теперь вспоминаем, что строка
        //                                         a[0] уже удалена и a[0][1] обращение к
        //                                        несуществующим данным и тут либо фигня в
        //                                        результатах либо программа падает
        free(a[i]);
    }
    free(a);
    getch();
    return 0;
}


Добавлено через 8 минут и 4 секунды
Еще раз повторю: в последнем ваше коде переменная a в функции main, переменная a в функции comp и переменная a в функции sum это абсолютно разные переменные ни когда не обменивающиеся значениями. И лишь по теории случайности с вероятностью 1 к бесконечности могут указать  на один и тот же адрес в памяти и в этом случае возможно ваша программа отработает правильно.

Добавлено через 13 минут и 53 секунды
Цитата(krot100500 @  30.12.2011,  03:14 Найти цитируемый пост)
Я ВКУРИЛ!!!!!Еххааа Voral СПАСИБИЩЕ!!!)
метод проб и ошибок рулит)))

Он рулит ровно до тех пор пока вы не осознаете, что самый быстрый путь - зачастую самый длинный. Читайте Кернигана и Ритчи!
Если бы вы сразу после первого поста начали чтение вы бы уже впитали те главы, что достаточны для решения вышей задачи. И сейчас бы уже имели готовое решение.
PM MAIL WWW   Вверх
krot100500
Дата 1.1.2012, 23:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 18
Регистрация: 26.12.2011

Репутация: нет
Всего: нет



Спасибки еще раз что потратил стока времени на объяснения) Мне это все-равно не помогло*( через годик, примерно ,вернусь разбирать заного, если голову не отобьют и востановят в универе(
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0974 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.