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

Поиск:

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


Шустрый
*


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

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



Для заданной матрицы размером 8 на 8 найти такие k, что k-я строка матрицы совпадает с k-м столбцом.
Найти сумму элементов в тех строках, которые содержат хотя бы один отрицательный элемент.

По первой части проблема в том, что он мне всегда выводит последнюю строку, даже если там нет совпадений. Я так понимаю, что не хватает проверки на ложность или на выход из массива? Но пытался вписать else и прога перестала работать вообще.

По всей проге вопрос такой: он мне считает все элементы начиная с 0 (как и полагается в массиве), но когда я пытаюсь сдвинуть цикл for (i=1; i=N-1; i++) всё рушится :(

И третий вопрос нафига тут flag? Без него прога не работала, я просто нагло скопировал часть с флагом и поэтому не врубаюсь фигли без него не работает.


Код

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

#define N 8
#define M 8

main ()
{      
       int i, j, sum=0, flag=0, array[N][M];
       
    srand(time(NULL)); 
    
    /*Создаю массив случайных чисел, размерность которого 8 на 8*/
  
      for(i=0; i<N; i++) 
        for(j=0; j<M; j++)
       array[i][j] = -1+ rand () % 9;   /*Заполняю массив случайными числами от -1 до 7*/    
  
      for(i=0; i<N; i++)
       {
        for(j=0; j<M; j++)
         printf("%2d ", array[i][j]);
       printf("\n");  
       }
    printf("\n");
    
    /* 1-ая часть. Нахожу такие k, что k-я строка матрицы совпадает с k-м столбцом */
    
   for(i=0; i<N; i++)
   {
     for (j=0; j<N; j++)
     flag = (array[i][j]==array[j][i]);
      if (flag) 
       printf("V %d stroke esti sovpadenie \n", i);         
        }
   printf("\n\n");
   
   
   /*2-часть, нахожу сумму строк с отрицательным элементом*/
   for(i=0; i<N-1; i++) 
    {
        for (j=0; j<N; j++) 
          if(array[i][j] < 0) /*ищу элементы массива которые меньше 0*/
        {
          for(j=0; j<N; j++) /*проход по строке с отрицательным элементом, для суммирования*/
            sum += array[i][j]; /*нахожу сумму элементов заданной строки*/
        
        printf("Ыumma otricatelinoi stroki %d ravna %d \n", i, sum);
        } 
    }
    printf("\n");
system("pause");
return 0;     
}



Это сообщение отредактировал(а) Kruger2 - 30.6.2011, 14:13
PM MAIL   Вверх
baldina
Дата 30.6.2011, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



Цитата(Kruger2 @  30.6.2011,  14:11 Найти цитируемый пост)
По первой части проблема в том, что он мне всегда выводит последнюю строку, даже если там нет совпадений. Я так понимаю, что не хватает проверки на ложность или на выход из массива? Но пытался вписать else и прога перестала работать вообще.

Цитата(Kruger2 @  30.6.2011,  14:11 Найти цитируемый пост)
for (j=0; j<N; j++)
     flag = (array[i][j]==array[j][i]);
      if (flag) 
       printf("V %d stroke esti sovpadenie \n", i);         

flag надо инициализировать на каждом шаге цикла по i:
Код

flag=0;
for (j=0; j<N; j++)
     flag = (array[i][j]==array[j][i]);
if (flag) 
     printf("V %d stroke esti sovpadenie \n", i);     

Цитата(Kruger2 @  30.6.2011,  14:11 Найти цитируемый пост)
когда я пытаюсь сдвинуть цикл for (i=1; i=N-1; i++

зачем?

Это сообщение отредактировал(а) baldina - 30.6.2011, 14:54
PM MAIL   Вверх
Kruger2
Дата 30.6.2011, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



baldina
Начал писать и придумал как решить проблемуsmile  У меня ответы получались начиная от 0. Но в printf указать просто i + 1).

Инициализировал flag нулем, но ничего не изменилось. Всегда выдает, что есть совпадение в последней строке.
PM MAIL   Вверх
baldina
Дата 30.6.2011, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



Цитата(Kruger2 @  30.6.2011,  15:27 Найти цитируемый пост)
 Всегда выдает, что есть совпадение в последней строке.

а в действительности нет совпадения?
PM MAIL   Вверх
Kruger2
Дата 30.6.2011, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Нет. Бывают совпадения в других строках. А последнюю выводит всегда, вне зависимости от того есть там совпадения или нет.

Добавлено @ 15:42
Вот блин, он мне и сложение не правильно дает, каждую строку после первой он начинает не с ноля, а с конечной суммы. Чорд чорд чорд)

Это сообщение отредактировал(а) Kruger2 - 30.6.2011, 15:43
PM MAIL   Вверх
baldina
Дата 30.6.2011, 16:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



Цитата(Kruger2 @  30.6.2011,  15:40 Найти цитируемый пост)
Нет. Бывают совпадения в других строках.

посмотрите внимательнее. а лучше - задайте массивы вручную.
http://codepad.org/tMdEtddz
PM MAIL   Вверх
newbieone
Дата 30.6.2011, 16:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



В условии же сказано о полном равенстве строки и столбца, верно? 
Цитата
такие k, что k-я строка матрицы совпадает с k-м столбцом

А у вас там в алгоритме выводится, что совпадение найдено, если есть хотя бы один такой элемент на позиции i,j, что симметричный ему элемент на j,i имеет то же значение... 
Код

for(i=0; i<N; i++) // в каждой строке
   {
     for (j=0; j<N; j++) // проходим по всем столбцам
     flag = (array[i][j]==array[j][i]); // нашли совпадение хоть в каком-то из симметричных элементов
      if (flag) 
       printf("V %d stroke esti sovpadenie \n", i); // равны всего два элемента => строка и столбец совпали? НЕТ НЕТ НЕТ!
        }
   printf("\n\n");

Попробуйте вот так, кажется, то, что нужно.
Код

    /* 1-ая часть. Нахожу такие k, что k-я строка матрицы совпадает с k-м столбцом */
    
    if(N==M) // имеет смысл сравнивать строку со столбцом, только если количество элементов в них равно
    {
        bool flag=false; // для того, чтобы знать, нашли хоть какие-то удовлетворяющие требованиям k, или нет
        short count; // количество совпавших элементов в k-ой строке и k-ом столбце
        for(i=0;i<N;i++)
        {
            count=0; // сначала никаких совпадений нет
            for(j=0;j<M;j++)
            {
                if(array[i][j]==array[j][i])
                    count++; // если совпала пара симметричных элементов, то на одно совпадение больше
                else
                    break; // если не совпала хотя бы пара, то уже строка и столбец не равны, можно закругляться
            }
            if(count==N) // совпало все N штук?
            {
                flag=true; // ну тогда хоть что-то мы выведем
                printf("these strings are equal: k = %d \n",i+1); // а именно: k-ый столбец и строка имеют одинаковые элементы 
            }
        }
        if(!flag) // не выводить вообще ничего плохо
            printf("there is no equality\n"); // потому, если удовлетворяющих условиям k-ых строк/столбцов нет, говорим об этом
    }
    else
    {
        printf("there can not be any equality\n"); // если размер строки не равен размеру столбца, говорим, что не будем ничего искать
    }


Это сообщение отредактировал(а) newbieone - 30.6.2011, 16:42
PM MAIL   Вверх
Kruger2
Дата 30.6.2011, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Всегда выдает: there is no equality =(
PM MAIL   Вверх
baldina
Дата 30.6.2011, 16:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



Цитата(newbieone @  30.6.2011,  16:34 Найти цитируемый пост)
симметричный ему элемент на j,i имеет то же значение... 

...на главной диагонали, i==j

Код

for(i=0; i<N; i++)
{
     flag=0;
     for (j=0; j<N; j++)
       if (i!=j && array[i][j]==array[j][i])
       {
          flag = 1;
          break;
       }
     if (flag) 
       printf("V %d stroke esti sovpadenie \n", i);         
}


Добавлено через 1 минуту и 55 секунд
это проверка совпадения хотябы одного элемента. если надо проверить все, то

Код

for(i=0; i<N; i++)
{
     flag=1;
     for (j=0; j<N; j++)
       if (array[i][j]!=array[j][i])
       {
          flag = 0;
          break;
       }
     if (flag) 
       printf("V %d stroke esti sovpadenie \n", i);         
}


Это сообщение отредактировал(а) baldina - 30.6.2011, 16:46
PM MAIL   Вверх
newbieone
Дата 30.6.2011, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Цитата
Всегда выдает: there is no equality =( 

а для случайно сгенерированной матрицы у вас, собственно, никогда и не будет никакой equality. вы смотрите на свою матрицу, на первую строку, потом на первый столбец. все элементы в строке и столбце одинаковые? очевидно, при использовании rand() для заполнения массива - нет.
Цитата
...на главной диагонали, i==j

это вы откуда взяли про главную диагональ? там идет прогонка по всему массиву
Код

for(i=0; i<N; i++)
   {
     for (j=0; j<N; j++)
     flag = (array[i][j]==array[j][i]);
      if (flag) 
       printf("V %d stroke esti sovpadenie \n", i);         
        }
   printf("\n\n");

Давайте для определенности N=8, i=1, j=0. Рассмотрим 4 строку:
Код

array[1][0]==array[0][1]

Отнюдь не главная диагональ.

Это сообщение отредактировал(а) newbieone - 30.6.2011, 16:56
PM MAIL   Вверх
baldina
Дата 30.6.2011, 17:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



я имел в виду, что array[i][j] всегда ==array[j][i] при i==j

Добавлено через 53 секунды
именно поэтому у него всегда последняя строка попадает: там у последнего проверяемого элемента j==i и, соответственно, flag==1
PM MAIL   Вверх
newbieone
Дата 30.6.2011, 17:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Главная диагональ там играет роль именно только в последнем элементе последней строки.
На предыдущих же строках главная диагональ алгоритму Kruger2 вообще не важна: flag затирается при переходе от элемента к элементу, первые N-1 элементов могут быть различны, а N-тый элемент строки, в случае равенства N-тому элементу столбца, выставит flag в положение true, что якобы приводит к решению о равенстве строки и столбца (по сути, для положительного ответа программы у автора должны быть равны лишь A последних элементов строки и столбца, где A>=1 и не обязательно равно размеру строки/столбца N).
Код

Вот блин, он мне и сложение не правильно дает, каждую строку после первой он начинает не с ноля, а с конечной суммы. Чорд чорд чорд)

Ну всё просто, нужно обнулять ваш аккумулятор (sum) в начале каждого прохода по строке.

Это сообщение отредактировал(а) newbieone - 30.6.2011, 17:25
PM MAIL   Вверх
Kruger2
Дата 30.6.2011, 17:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Видимо я не понимаю задания. У меня получается есть допустим массив:

1 1 1 1
1 2 3 4
1 3 3 2

Вот тут первая строка совпадет с первым столбцом и только такой выдаст нужный ответ?
PM MAIL   Вверх
newbieone
Дата 30.6.2011, 17:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Kruger2, внимательнее. В общем случае, если вы хотите, чтобы строка совпадала со столбцом, то количество элементов в них должно быть одинаковым (т.е. матрица должна быть квадратной). Иначе как вы, например, для вашего примера:
Код

1 1 1 1
1 2 3 4
1 3 3 2

скажете, равен ли элемент [0][3]=1 элементу [3][0], если у вас четвертая строка отсутствует?
Если четвертую строку всё-таки добавить как-то так:
1 1 1 1
1 2 3 4
1 3 3 2
1 6 5 3
то, безусловно, ответом будет k=1 (т.е. только 1 строка и 1 столбец содержат одинаковые элементы).

Это сообщение отредактировал(а) newbieone - 30.6.2011, 18:00
PM MAIL   Вверх
baldina
Дата 30.6.2011, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



newbieone, похоже, вы читаете невнимательно)))) долго объясняете то, что уже говорено
PM MAIL   Вверх
Kruger2
Дата 30.6.2011, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Код

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

#define N 8
#define M 8

main ()
{      
       int i, j, sum=0, flag=0;
           
          int  array[N][M] = {
                           { 2, 2, 2, 2, 2, 2, 2, 2 },
                           { 1, 2, 7, 6, 0, -8, 3, 5 },
                           { 2, 2, 1, 8, 1, 4, 9, 3 },
                           { 9, 2, 8, 5, 2, 0, 0, 6 },
                           { 7, 2, 1, 3, 9, 3, 9, 1 },
                           { 8, 2, 4, 9, 1, -6, 4, 9 },
                           { 0, 2, 9, 0, 9, 4, 8, 8 },
                           { 1, 2, 3, 2, 8, 2, 8, 0 }
                           }; 
  
        for(i=0; i<N; i++) 
        {
                 for(j=0; j<M; j++)
         printf("%2d ", array[i][j]);
         printf("\n");
         }
          printf("\n\n");
    
    
    if(N==M) 
    {
      bool flag=false; 
        short count; 
        
        for(i=0; i<N; i++)
        {
            count=0; 
            for(j=0; j<M; j++)
            {
                if(array[i][j]==array[j][i])
                    count++; 
                else
                    break; 
            }
            if(count==N) 
            {
                flag=true; 
                printf("these strings are equal: k = %d \n", i+1); 
            }
         }
        if(!flag) 
            printf("there is no equality\n"); 
    }
    else
    {
        printf("there can not be any equality\n"); 
    }
printf("\n\n");

system("pause");
return 0;     
}



Ответ, зер из но иквилти. Что не так?)
PM MAIL   Вверх
newbieone
Дата 30.6.2011, 18:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



baldina, возможно, между нами имело место быть недопонимание.
Kruger2, укажите номер k, для которого k-ая строка вашей матрицы содержит те же элементы (слева направо), что k-ый её столбец (сверху вниз). Я такого не вижу.
PM MAIL   Вверх
Kruger2
Дата 30.6.2011, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Не понимаю, где указать и что
PM MAIL   Вверх
newbieone
Дата 30.6.2011, 18:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Да здесь укажите, в виде ответа в теме  smile 
Код

 int  array[N][M] = {
                           { 2, 2, 2, 2, 2, 2, 2, 2 },
                           { 1, 2, 7, 6, 0, -8, 3, 5 },
                           { 2, 2, 1, 8, 1, 4, 9, 3 },
                           { 9, 2, 8, 5, 2, 0, 0, 6 },
                           { 7, 2, 1, 3, 9, 3, 9, 1 },
                           { 8, 2, 4, 9, 1, -6, 4, 9 },
                           { 0, 2, 9, 0, 9, 4, 8, 8 },
                           { 1, 2, 3, 2, 8, 2, 8, 0 }
                           }; 

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

Для заданной матрицы размером 8 на 8 найти такие k, что k-я строка матрицы совпадает с k-м столбцом.

То есть, номер строки и номер столбца должны быть одинаковыми. Вы можете сравнить 1 строку с 1 столбцом, 2ую строку со 2ым столбцом, но не можете сравнивать 1ю строку со 2 столбцом. Ферштейн?
PM MAIL   Вверх
Kruger2
Дата 30.6.2011, 18:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



ферштейн. убился об стену:(
PM MAIL   Вверх
triclosan
Дата 30.6.2011, 18:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


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

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



Kruger2, так это же реализацию значительно упрощает.
PM MAIL   Вверх
Kruger2
Дата 30.6.2011, 18:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Последний вопросsmile



Код

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

#define N 8
#define M 8

m   
       int i, j, sum=0, flag=0;
           
          int  array[N][M] = {
                           { 2, 2, 2, 2, 2, 2, 2, 2 },
                           { 2, 2, 2, 2, 2, 2, 2, 2 },
                           { 2, 2, -1, 8, 1, 4, 9, 3 },
                           { 9, 2, 8, 5, 2, 0, 0, 6 },
                           { 7, 2, 1, 3, 9, 3, 9, 1 },
                           { 8, 2, 4, 9, 1, -6, 4, 9 },
                           { 0, 2, 9, 0, 9, 4, 8, 8 },
                           { 1, 2, -3, 2, 8, 2, 8, 0 }
                           }; 
  
        for(i=0; i<N; i++) 
        {
                 for(j=0; j<M; j++)
         printf("%2d ", array[i][j]);
         printf("\n");
         }
          printf("\n\n");
    
    
    
    if(N==M) 
    {
      bool flag=false; 
        short count; 
        
        for(i=0; i<N; i++)
        {
            count=0; 
            for(j=0; j<M; j++)
            {
                if(array[i][j]==array[j][i])
                    count++; 
                else
                    break; 
            }
            if(count==N) 
            {
                flag=true; 
                printf("these strings are equal: k = %d \n", i+1); 
            }
        }
        if(!flag) 
            printf("there is no equality\n"); 
   
}
printf("\n\n");
   
  
   for(i=0; i<N-1; i++) 
    {
     sum=0;  
        for (j=0; j<N; j++) 
          if(array[i][j] < 0) 
        {
          for(j=0; j<N; j++) 
                     sum += array[i][j];
                printf("summa otricatel stroki %d ravna %d \n", i+1, sum);
        } 
    }
    printf("\n");
system("pause");
return 0;     
}ain ()
{   



Вот тут обнуляю сум. Всё стало работать норм кроме одного. Не считает последнюю строку, хотя там есть отрицательное число. Почему же он его не видит?:( Думал, может в последнем цикле фор должно <= но нет)
Код

for(i=0; i<N-1; i++) 
    {
     sum=0;  
        for (j=0; j<N; j++) 
          if(array[i][j] < 0) 
        {
          for(j=0; j<N; j++) 
         
            sum += array[i][j]; /*íàõîæó ñóììó ýëåìåíòîâ*/
        
        printf("summa otricatel stroki %d ravna %d \n", i+1, sum);
        } 
    }


Добавлено через 1 минуту и 15 секунд
triclosan 
Конечно упрощает. Трудно решать задачу не понимая, чего от тебя хотятsmile

Это сообщение отредактировал(а) Kruger2 - 30.6.2011, 18:21
PM MAIL   Вверх
newbieone
Дата 30.6.2011, 18:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Попробуйте, ответ должен быть: k=1, k=3.
Код

int  array[N][M] = {
                           { 2, 2, 2, 2, 2, 2, 2, 2 },
                           { 2, 2, 2, 6, 0, -8, 3, 5 },
                           { 2, 2, 1, 8, 1, 4, 9, 3 },
                           { 2, 2, 8, 5, 2, 0, 0, 6 },
                           { 2, 2, 1, 3, 9, 3, 9, 1 },
                           { 2, 2, 4, 9, 1, -6, 4, 9 },
                           { 2, 2, 9, 0, 9, 4, 8, 8 },
                           { 2, 2, 3, 2, 8, 2, 8, 0 }
                           }; 

По поводу второго задания: у вас в первой же строчке приведенного кода i должно меняться от 0 до N, а меняется до N-1, потому и нет последней строки.
Код

for(i=0; i<N-1; i++) // НЕТ НЕТ НЕТ! нужно так: for (i=0; i<N ; i++)
    {
     sum=0;  
        for (j=0; j<N; j++) 


Это сообщение отредактировал(а) newbieone - 30.6.2011, 18:44
PM MAIL   Вверх
voral
Дата 30.6.2011, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Код

#include <stdio.h>
#include <stdlib.h>
#define SIZE 8

int A[SIZE][SIZE]= {
                           { 2, 2, 2, 2, 2, 2, 2, 2 },
                           { 2, 2, 2, 6, 0, -8, 3, 5 },
                           { 2, 2, 1, 8, 1, 4, 9, 3 },
                           { 2, 2, 8, 5, 2, 0, 0, 6 },
                           { 2, 2, 1, 3, 9, 3, 9, 1 },
                           { 2, 2, 4, 9, 1, -6, 4, 9 },
                           { 2, 2, 9, 0, 9, 4, 8, 8 },
                           { 2, 2, 3, 2, 8, 2, 8, 0 }
                           };;

void compareLine(int i)
{
    int j;
    for (j=0;j<SIZE;++j)
        if (A[i][j]!=A[j][i])
            return;
    printf("K=%d\n",i+1);
}

void sum(int i)
{
    int j, result=0, fexists=0;
    for (j=0;j<SIZE;++j)
    {
        result+=A[i][j];
        if (A[i][j]<0) fexists=1;
    }
    if (fexists==1) printf("sum line %d: %d\n",i+1,result);
}

int main()
{
    int i;
    for (i=0;i<SIZE;++i)
    {
        compareLine(i);
        sum(i);
    }
    
}


Это сообщение отредактировал(а) voral - 30.6.2011, 18:50
PM MAIL WWW   Вверх
Kruger2
Дата 30.6.2011, 19:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



newbieone 
Большой спасибо за помощь, разобрался и всё заработало. Плюсище от меня в репутацию поставьте человеку! =)
За код с подробными комментариями я бы вообще пивом угостил, если б мог. как правило приходиться голову ломать, что для чегоsmile) Реально большое спасибо.


voral 
Элегантно. Тоже спасибо, плюс в репу от меня!smile

baldina
Тоже спасибо, тоже плюсикsmile
PM MAIL   Вверх
borisbn
Дата 30.6.2011, 19:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



Цитата(voral @  30.6.2011,  18:40 Найти цитируемый пост)
if (A[i][j]<0) fexists=1;

Код
if ( fexists == 0 && A[ i ][ j ] < 0 ) fexists = 1;

 smile 

Kruger2, тебе до сотни постов немного осталось. сам и наплюсуешь smile

Это сообщение отредактировал(а) borisbn - 30.6.2011, 19:13


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
newbieone
Дата 30.6.2011, 19:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



borisbn, а это критично? Результаты будут верными и для вашего варианта, и для кода voral, а вот алгоритм - оптимальней ли?
Код

if ( fexists == 0 && A[ i ][ j ] < 0 ) fexists = 1;

Вне зависимости от знака элементов строки будут произведены N сравнений на равенство нулю, N обращений к элементу массива и проверок на отрицательность элемента, 1 присваивание. 2N+1 операция (или даже 3N+1, если обращение к элементу массива и сравнение считать двумя различными), если я нигде не наврал.
Теперь здесь:
Код

if (A[i][j]<0) fexists=1;

В худшем случае, когда все элементы отрицательны, имеем N присваиваний и N сравнений. 2N операций (ну или 3N, при тех же условиях, что и выше). Всё, конечно, поменяется, если вы скажете, что операция присваивания требует больше ресурсов, чем операция сравнения, но намного ли? Надо еще учесть, что далеко не всегда будет худший вариант, возможно, только один из элементов будет отрицательным, тогда будем иметь всего N+1 (2N+1) операций против 2N+1 (или 3N+1 соответственно). Тогда исходный алгоритм будет требовать аж на N операций меньше, чем предложенный вами. smile

UPD.: Хотя, если еще чуть подумать, можно вспомнить о short-circuiting, когда первое сравнение даст false и ничего больше вычисляться не будет...
Код

if ( fexists == 0 && A[ i ][ j ] < 0 ) fexists = 1;

В общем, всё это очень спорно  smile 

Это сообщение отредактировал(а) newbieone - 30.6.2011, 19:50
PM MAIL   Вверх
voral
Дата 30.6.2011, 20:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(newbieone @  30.6.2011,  19:26 Найти цитируемый пост)
В общем, всё это очень спорно

Да нет. Тут все бесспорно. Поправка правильная. В любом случае если вызывает сомнение можно разложить этот if на два - и это будет шустрее чем мой вариант smile
PM MAIL WWW   Вверх
newbieone
Дата 30.6.2011, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Код

#include <stdio.h>
#include <stdlib.h>
#include <ctime>
#include <iostream>
#define SIZE 15000
int **A;
void compareLine(int i)
{
    int j;
    for (j=0;j<SIZE;++j)
        if (A[i][j]!=A[j][i])
            return;
    //printf("K=%d\n",i+1);
}
void sum(int i)
{
    int j, result=0, fexists=0;
    for (j=0;j<SIZE;++j)
    {
        result+=A[i][j];
        if (A[i][j]<0) fexists=1;
        //if ( fexists == 0 && A[ i ][ j ] < 0 ) fexists = 1;
    }
    if (fexists==1) return; //printf("sum line %d: %d\n",i+1,result);
}
void print()
{
    for(int i=0; i<SIZE; i++)
    {
        for(int j=0; j<SIZE; j++)
            printf("%2d ", A[i][j]);
        printf("\n");  
    }
    printf("\n");
}
void fillArray()
{
    A=new int*[SIZE];
    for(int i=0;i<SIZE;i++)
        A[i]=new int [SIZE];
    srand(time(NULL)); 

    for(int i=0; i<SIZE; i++) 
        for(int j=0; j<SIZE; j++)
            A[i][j] = -1+ rand () % 9;  
}
void main()
{
    

    fillArray();
    //print();

    for (int i=0;i<SIZE;++i)
    {
        compareLine(i);
        sum(i);
    }

    for(int i=0; i<SIZE;i++)
        delete A[i];
    delete []A;

    std::cout << "It took: " << double(clock()) / CLOCKS_PER_SEC << " seconds" << std::endl;
    
}

Тестировал для SIZE=15000, заполнение массива случайными числами.
Код
if ( fexists == 0 && A[ i ][ j ] < 0 ) fexists = 1;

It took: 15.312 seconds
Код
if (A[i][j]<0) fexists=1;

It took: 16 seconds

Даже не знаю.

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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



>It took: 15.312 seconds код
>It took: 16 seconds
IMHO всего на 15000 7%  выиграша уже не плохо

Если это кому-нить нужно smile, ессно


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
voral
Дата 30.6.2011, 22:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Не совсем правильное сравнение. Тут основное время занимает заполнение массива. Вот я почистил код. Каждый вариант запускается по три раза:
Код

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define SIZE 15000
#define NN 3

int A[SIZE][SIZE];
void sum(int i)
{
    int j, result=0, fexists=0;
    for (j=0;j<SIZE;++j)
    {
        result+=A[i][j];
        if ((fexists==0)&&(A[i][j]<0)) fexists=1;
    }
}
void sum2(int i)
{
    int j, result=0, fexists=0;
    for (j=0;j<SIZE;++j)
    {
        result+=A[i][j];
        if (A[i][j]<0) fexists=1;
    }
}

int main()
{
    static int min = -1;
    static int max = 9;
    int i,j, fok;
    for (i=0;i<SIZE;++i)
        for (j=0;j<SIZE;++j)
            A[i][j]=min + rand()%(max-min+1);
    printf("Go\n");
    long c ;
    for (j=0;j<NN;++j)
    {
        c=clock();
        for (i=0;i<SIZE;++i)
            sum(i);
        c=clock()-c;
        printf("%ld\n",c);
    }
    for (j=0;j<NN;++j)
    {
        c=clock();
        for (i=0;i<SIZE;++i)
            sum2(i);
        c=clock()-c;
        printf("%ld\n",c );
    }
    
}

В результате у меня получися следующий вывод:
Код

Go
1630000
1630000
2930000
4120000
4120000
4130000

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


аСинизатор
***


Профиль
Группа: Завсегдатай
Сообщений: 1721
Регистрация: 10.5.2003
Где: Эрец-Исраэль

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



Цитата(voral @  30.6.2011,  22:34 Найти цитируемый пост)
В результате у меня получися следующий вывод:

А если как-то так попробовать?
Код
void sum(int i)
{
    int    j, result = 0;

    for(j = 0; j < SIZE; j++)
    {
        result += A[i][j];

        if(A[i][j] < 0)
            for(++j; j < SIZE; ++j)
                result += A[i][j];
    }
}



Это сообщение отредактировал(а) Dov - 1.7.2011, 00:10


--------------------
Тут вечности запах томительный,
И свежие фрукты дешевые, 
А климат у нас – изумительный, 
И только соседи – #уевые. 
                           Игорь Губерман.
PM   Вверх
voral
Дата 1.7.2011, 00:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Да это будет быстрее. 

Это сообщение отредактировал(а) voral - 1.7.2011, 00:38
PM MAIL WWW   Вверх
newbieone
Дата 1.7.2011, 09:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Окей, практика показала увеличение производительности. А теперь теоретически это как-то можно объяснить? Я вот на прошлой странице пытался провести сравнение сложности алгоритмов "на бумажке" по количеству машинных операций, но, видимо, оно чего-то (многого) не учитывает.

Это сообщение отредактировал(а) newbieone - 1.7.2011, 09:47
PM MAIL   Вверх
voral
Дата 1.7.2011, 10:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(newbieone @  1.7.2011,  09:45 Найти цитируемый пост)
Окей, практика показала увеличение производительности. А теперь теоретически это как-то можно объяснить? Я вот на прошлой странице пытался провести сравнение сложности алгоритмов "на бумажке" по количеству машинных операций, но, видимо, оно чего-то (многого) не учитывает.

Это о последнем алгоритме?
Там все просто. 
Сначала бежим по каждому элементу сторки, прибавляем его у сумме и сравниваем.
Как только нашли первый отрицательный элемент, нас уже не интересует есть ли еще отрицательные, по этому мы уходим в продолжение цикла где нет проверок на отрицательность, т.е. избавляемся от лишнй операции на каждую итерацию. (в предыдущем "быстром" варианте мы все равно проверяли флаг на равенство 1 или 0)
PM MAIL WWW   Вверх
newbieone
Дата 1.7.2011, 10:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



voral, я имел ввиду математическое пояснение в терминах теории сложности вычислений (сложности алгоритмов).
Цитата
о последнем алгоритме?

Вашего первоначального и того, что предложил borisbn.

Это сообщение отредактировал(а) newbieone - 1.7.2011, 10:26
PM MAIL   Вверх
voral
Дата 1.7.2011, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(newbieone @ 30.6.2011,  19:26)
Теперь здесь:
Код

if (A[i][j]<0) fexists=1;

В худшем случае, когда все элементы отрицательны, имеем N присваиваний и N сравнений. 2N операций (ну или 3N, при тех же условиях, что и выше). Всё, конечно, поменяется, если вы скажете, что операция присваивания требует больше ресурсов, чем операция сравнения, но намного ли? Надо еще учесть, что далеко не всегда будет худший вариант, возможно, только один из элементов будет отрицательным, тогда будем иметь всего N+1 (2N+1) операций против 2N+1 (или 3N+1 соответственно).

а вы про этот пост где N расписывали smile
Ну тогда както так:
В худшем случае (кагда нет отрицательных числ)
мы имеем N сравнений и ни одногоприсваивания
В лучшем случае когда первый элемент в строке отрицателен имеем 1 сравнени и так же ни одного присваивания.

Итак имеем от 1 до N (в зависимости от позиции отрицательного числа) операций против от N до 2N

Добавлено через 4 минуты и 35 секунд
А вообще. Если целью поставить быстродействие и если позволяет процедура заполнения матрицы. Добавить еще один одномерный массив. При вводе нового элемента матрицы анализировать существование отрицательного значения и заносить номер строки в массив. Хотя в этом случае (такой ввод) моно собственну и суму здесь же считать. Но это уже теряем гибкость.
PM MAIL WWW   Вверх
newbieone
Дата 1.7.2011, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



voral, не могу с вами согласиться. У вас же там в условном операторе два условия через &&, сравнений соответственно будет в два раза больше, плюс вы забываете о сравнениях (о первом из них, второе из-за short-circuiting не будет вычисляться) уже после присваивания...
Если пытаться анализировать этим способом, имеем практически одинаковые результаты: N+2 до 2N против N+1 до 2N.
Код
if ( fexists == 0 && A[ i ][ j ] < 0 ) fexists = 1;

Если первый элемент отрицательней, проведется 2 сравнения, 1 присваивание, и после этого еще N-1 сравнений (т.к. fexists станет равным единице, то первое сравнение даст false и дальше выражение вычисляться не будет). В сумме N+1 сравнений и 1 присваивание, т.е. N+2 операций.
Если все положительные, то fexists всегда остается равным нулю и имеем 2N сравнений.
Код
if (A[i][j]<0) fexists=1;

Здесь если существует единственный отрицательный элемент, N сравнений и 1 присваивание, т.е. N+1 операция.
Если все отрицательные, N сравнений и N присваиваний, т.е. 2N операций.

Другое дело, что способ, судя по практическим результатам, не совсем верен. Практика с теорией расходятся...

Это сообщение отредактировал(а) newbieone - 1.7.2011, 13:50
PM MAIL   Вверх
voral
Дата 1.7.2011, 17:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(newbieone @  1.7.2011,  13:47 Найти цитируемый пост)
voral, не могу с вами согласиться. У вас же там в условном операторе два условия через &&, сравнений соответственно будет в два раза больше, плюс вы забываете о сравнениях (о первом из них, второе из-за short-circuiting не будет вычисляться) 

видимо мы о разном. Я разложил именно поселедний самый шустрый вариант.
Этот же случай 
Код

if ( fexists == 0 && A[ i ][ j ] < 0 ) fexists = 1;

я понимаю так. 
Самое плохое когда нет отрицательных
два сравнения, сложение энд т.е. 3N - операций 
Самое хорошее когда первое отрицательное
первая итерация  два сравнения, сложение энд и присваивание 4 операции
остальные итерации одно сравнение
т.е. (N-1)+4
Т.е получаем от N+3 до 3N  против N+1 до 2N, (кстати операция операции рознь и && совсем не одно и то же что сравнение)

К тому же. У нас диапазон чисел от -1 до 9. При размере матрицы 15000 шанс что в строке не будет отрицательных чисел очень мал. Т.е. скорее всего исходный случай с одним сравнением будет стремиться именно к 2N, В то время как где два сравнения врят ли дотянет до 3N...
Думаю если уменьшить размер, или увеличить диапазон чисел.... ТО может быть преимущество перейдет.

Это конечно все просто рассуждения можно попробовать посмотреть на практике. Дизасемблировать оба варианта, чтоб посмотреть как это выглядит на асме; и сделать с промежуточным выводом значений... smile
PM MAIL WWW   Вверх
newbieone
Дата 1.7.2011, 18:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Хехе, ну вот, а говорили на предыдущей странице, что
Цитата
Тут все бесспорно.

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


Бывалый
*


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

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



Вот еще небольшой тестик
Код

#include <stdio.h>
int main()
{
    int size=15000, count=15000;
    int min=-1, max = 9;
    int i,j,k;
    int stat_max=0,stat_average=0,stat_count=0;
    

    srand(time(NULL));
    for (i=0;i<count;++i)
        for (j=0;j<size;++j)
        {
            k=rand()%(max-min+1)+min;
            if (k<0)
            {
                if (stat_max<j) stat_max=j;
                stat_average+=j;
                ++stat_count;
                break;
            }
        }
        printf("Negative exists in %d from %d    Max=%d Average=%d\n",stat_count,count,stat_max,stat_average/count);

}

Результат:
Код

Negative exists in 15000 from 15000    Max=100 Average=10


Добавлено через 2 минуты и 54 секунды
При размере строки 11 все равно неплохой результат:
Цитата

Negative exists in 9834 from 15000    Max=10 Average=4


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


Шустрый
*


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

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



Через несколько глав снова вернулся к этому заданию, но уже в более продвинутом виде. 
Теперь необходимо решить туже задачу, с динамическим выделением памяти.

Тут я взял за основу код уважаемого voral, т.к. удобнее дописать функциюsmile

вот основа:


Код

#include <stdio.h>
#include <stdlib.h>
#define SIZE 8
int A[SIZE][SIZE]= {
                           { 2, 2, 2, 2, 2, 2, 2, 2 },
                           { 2, 2, 2, 6, 0, -8, 3, 5 },
                           { 2, 2, 1, 8, 1, 4, 9, 3 },
                           { 2, 2, 8, 5, 2, 0, 0, 6 },
                           { 2, 2, 1, 3, 9, 3, 9, 1 },
                           { 2, 2, 4, 9, 1, -6, 4, 9 },
                           { 2, 2, 9, 0, 9, 4, 8, 8 },
                           { 2, 2, 3, 2, 8, 2, 8, 0 }
                           };;
                               
void compareLine(int i)
{
    int j;
    for (j=0;j<SIZE;++j)
        if (A[i][j]!=A[j][i])
            return;
    printf("K=%d\n",i+1);
}
void sum(int i)
{
    int j, result=0, fexists=0;
    for (j=0;j<SIZE;++j)
    {
        result+=A[i][j];
        if (A[i][j]<0) fexists=1;
    }
    if (fexists==1) printf("sum line %d: %d\n",i+1,result);
}
int main()
{
    int i;
    for (i=0;i<SIZE;++i)
    {
        compareLine(i);
        sum(i);
    }

system("pause");
return 0;
}



Вот что я добавил: 


Код

#include <stdio.h>
#include <stdlib.h>
#define SIZE 8
int A[SIZE][SIZE]= {
                           { 2, 2, 2, 2, 2, 2, 2, 2 },
                           { 2, 2, 2, 6, 0, -8, 3, 5 },
                           { 2, 2, 1, 8, 1, 4, 9, 3 },
                           { 2, 2, 8, 5, 2, 0, 0, 6 },
                           { 2, 2, 1, 3, 9, 3, 9, 1 },
                           { 2, 2, 4, 9, 1, -6, 4, 9 },
                           { 2, 2, 9, 0, 9, 4, 8, 8 },
                           { 2, 2, 3, 2, 8, 2, 8, 0 }
                           };;
                           
void malloc (int** Array)
{
    
    Array = (int **)malloc(SIZE*sizeof(int* ));
         if(!Array) 
     {
       printf("Memory not allocated. \n");
      return;
     }
     int i;
     for (i=0; i< SIZE; i++)
     {
       Array[i]= (int *) malloc(SIZE*sizeof (int ));
       if (!Array[i])
       {
         printf("Memory not allocated2 \n");
         return;
       }
     }
}

void freememory(int** Array)
{
       int i;
       for(i=0; i<SIZE; i++)
       {
         free (Array[i]);
       }
       free(Array);
}
     
void compareLine(int i)
{
    int j;
    for (j=0;j<SIZE;++j)
        if (A[i][j]!=A[j][i])
            return;
    printf("K=%d\n",i+1);
}
void sum(int i)
{
    int j, result=0, fexists=0;
    for (j=0;j<SIZE;++j)
    {
        result+=A[i][j];
        if (A[i][j]<0) fexists=1;
    }
    if (fexists==1) printf("sum line %d: %d\n",i+1,result);
}
int main()
{
    int i;
    for (i=0;i<SIZE;++i)
    {
        compareLine(i);
        sum(i);
    }

system("pause");
return 0;
}



Значит функция maloc вроде бы написана без синтаксических ошибок, ибо компилятор не матерится. Однако как проверить правильно ли выделяется память я не знаю, поэтому прошу провеhить код функции maloc

Далее, то что код функции freememory должен находится не тут я понимаю (ибо выделил память и тут же аннулировал), но где она должна находиться? После main? прямо перед main? Будьте добры, подскажите.
PM MAIL   Вверх
voral
Дата 11.7.2011, 14:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(Kruger2 @  11.7.2011,  12:42 Найти цитируемый пост)
Далее, то что код функции freememory должен находится не тут я понимаю (ибо выделил память и тут же аннулировал), но где она должна находиться? После main? прямо перед main? Будьте добры, подскажите. 

При выделении памяти ты заносишь адрес в переменную. Переменная имеет свою область видимости. А также, если она не глобальная, может пропасть при выходе из функции в которой существует.

Ты сделал свои обертки для malloc и free.  Желательно их вызывать (для одной области) в  рамках однной функции - в которой живет переменная хранящая адрес.

Однако, могут быть ситуации когда ты передаешь адрес в другую функцию/поток, а из той в которой создал уходишь... Тогда уже там надо позаботиться об освобождении.
Например
Код

myType* getNewObject()
{
  myType* Result= (myType*)malloc(sizeof(myType));
  return Result;
}

Переменная Result будет уничтожена. Но память останется выделенной.....
PM MAIL WWW   Вверх
Kruger2
Дата 11.7.2011, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Т.е. мне надо вызвать функцию малок внутри каждой из моих двух функций или вызвать её в мейне перед выполнением двух других функций?

Добавлено @ 14:40
и получается освобождать память тоже не надо, т.к. нет глобальных переменных ?

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


Шустрый
*


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

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



Код

#include <stdio.h>
#include <stdlib.h>
#define SIZE 8
int A[SIZE][SIZE]= {
                           { 2, 2, 2, 2, 2, 2, 2, 2 },
                           { 2, 2, 2, 6, 0, -8, 3, 5 },
                           { 2, 2, 1, 8, 1, 4, 9, 3 },
                           { 2, 2, 8, 5, 2, 0, 0, 6 },
                           { 2, 2, 1, 3, 9, 3, 9, 1 },
                           { 2, 2, 4, 9, 1, -6, 4, 9 },
                           { 2, 2, 9, 0, 9, 4, 8, 8 },
                           { 2, 2, 3, 2, 8, 2, 8, 0 }
                           };;
                           
void inMemory (int** Array)
{
    
    Array = (int **)malloc(SIZE*sizeof(int* ));
         if(!Array) 
     {
       printf("Memory not allocated. \n");
      return;
     }
     int i;
     for (i=0; i< SIZE; i++)
     {
       Array[i]= (int *) malloc(SIZE*sizeof (int ));
       if (!Array[i])
       {
         printf("Memory not allocated2 \n");
         return;
       }
     }
}

void freeMemory(int** Array)
{
     
       int i;
       for(i=0; i<SIZE; i++)
       {
         free (Array[i]);
       }
       free(Array);
}
     
void compareLine(int i)
{
    int j, b,c;
      void inMemory(int** b);
    for (j=0;j<SIZE;++j)
        if (A[i][j]!=A[j][i])
            return;
    printf("K=%d\n",i+1);
      void freeMemory(int** c);
}
void sum(int i)
{
    int j, result=0, fexists=0, b, c;
      void inMemory(int** b);
    for (j=0;j<SIZE;++j)
    {
        result+=A[i][j];
        if (A[i][j]<0) fexists=1;
    }
    if (fexists==1) printf("sum line %d: %d\n",i+1,result);
      void freeMemory(int** c);
}
int main()
{
    int i;
    for (i=0;i<SIZE;++i)
    {
        compareLine(i);
        sum(i);
    }

system("pause");
return 0;
}



Вызываю внутри каждой функции сначала inmemory, затем freememory (решил переименовать малок в инмемори, что бы внести ясность)

Это сообщение отредактировал(а) Kruger2 - 11.7.2011, 14:53
PM MAIL   Вверх
baldina
Дата 11.7.2011, 15:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



Цитата(voral @  11.7.2011,  14:21 Найти цитируемый пост)
Ты сделал свои обертки для malloc и free.  Желательно их вызывать (для одной области) в  рамках однной функции - в которой живет переменная хранящая адрес.

сделав обертки, мы получили те же самые malloc и free, концептуально ничего нового.
в вопросах управления ресурсами, в т.ч. памятью, важно понятие владельца. именно владелец отвечает за своевременное удаление объекта (освобождение ресурса). выделение ресурса может происходить вне владельца, важно, что бы сразу после выделения установить владельца.
на примере умных указателей:
Код

auto_ptr<int> my_ptr (new int);

здесь выделение ресурса происходит вне владельца - переменной my_ptr, но владелец устанавливается сразу. освобождение памяти произойдет, кода закончится время жизни my_ptr. если между выделением ресурса и установкой владельца что-то происходит
Код

int *ptr = new int;
.... // тут еще какой-то код
auto_ptr<int> my_ptr (ptr);

есть вероятность возникновения исключения, тогда память не будет освобождена.
PM MAIL   Вверх
Kruger2
Дата 11.7.2011, 15:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



   В общих чертах я это понимаю. Теорию из книги прочитал, теперь пытаюсь перенести теорию на практику. 
   Если я вас правильно понял, мне не нужно освобождать память по окончанию выполнения функции, т.к. локальная переменная сама сотрется при выходе из функции? 

   Хорошо, тогда правильно ли я вызываю функцию динамического распределения памяти? Внутри функции, которая оперирует интересующими меня переменными я вызываю функцию выделения памяти, т.е. всё верно? Потому что я сомневался, может я в мейне должен вызвать функцию malloc(inMemory) перед началом выполнения двух других функций, но это получается нелогичным, т.к. память выделиться на все последующие функции и захламится мусором этих самых функций и при этом не произойдет очистки памяти. Верно?
PM MAIL   Вверх
baldina
Дата 11.7.2011, 15:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



Kruger2, тут какая-то каша в коде.
давай вернемся к задаче. требуется написать управление памятью и доступом для квадратной матрицы.
определим операции
1. создать матрицу порядка N
2. получить доступ (для чтения или установки значения) к элементу (i,j) матрицы
3. освободить занимаемую матрицей память

пусть у нас будет
Код

struct matrix {...}; // матрица
void create_matrix (matrix*, int n); // функция инициализации матрицы и выделения памяти
void destroy_matrix (matrix*); // функция освобождения памяти
int get_m (const matrix*, int i, int j); // функция получения значения элемента 
void set_m (matrix*, int i, int j, int value); // функция установки значения элемента 

предлагаю структуру сделать такой:
Код

struct matrix {
  int size;
  int *data;
}; 

тогда data должен указывать на память размером size*size, а элемент (i,j) в data находится по индексу i*size+j
остальное, думаю, сам реализуешь.
ЗЫ: с использованием классов это можно сделать намного изящнее

Добавлено через 3 минуты и 14 секунд
Цитата(Kruger2 @  11.7.2011,  15:12 Найти цитируемый пост)
 правильно ли я вызываю функцию динамического распределения памяти

совсем не вызываешь
Цитата(Kruger2 @  11.7.2011,  14:52 Найти цитируемый пост)
      void inMemory(int** b);

это не вызов, а объявление

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


Шустрый
*


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

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



Цитата(baldina @  11.7.2011,  15:17 Найти цитируемый пост)
остальное, думаю, сам реализуешь.


Это зря, структуры не изучал ещё.

Совершенно непонял
Цитата(baldina @  11.7.2011,  15:17 Найти цитируемый пост)
struct matrix {...}; // матрица
void create_matrix (matrix*, int n); // функция инициализации матрицы и выделения памяти
void destroy_matrix (matrix*); // функция освобождения памяти
int get_m (const matrix*, int i, int j); // функция получения значения элемента 
void set_m (matrix*, int i, int j, int value); 


Матрица у меня уже есть, зачем мне её ещё раз создавать, зачем мне функция получения значения элемента?

Брр, стало только хуже. Я хоть немного понимал, что я и как делаю. У меня была задача состоящая из двух функций, по идее мне достаточно было выделить память под эти две функции, что бы решить новое задание. Но теперь весь код каша? А в каком месте то каша? сейчас есть 4 функции, 2 из них решают основное задание, а 2 другие это выделение памяти и очистка. Вроде до каши ещё далеко  smile 
PM MAIL   Вверх
baldina
Дата 11.7.2011, 15:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



Цитата(Kruger2 @  11.7.2011,  15:12 Найти цитируемый пост)
локальная переменная сама сотрется при выходе из функции? 

локальная сотрется, а то что было выделено при помощи malloc - нет.
что бы динамическое распределение происходило так же просто и естественно, как это делается для локальных переменных, потредуется класс, в конструкторе которого выделяешь память, а в деструкторе освобождаешь.
Код

struct my {
  int *ptr;
  my () { ptr = new int[10]; }
 ~my () { delete [] ptr; }
};

int main ()
{
   my m; // здесь вызывается конструктор, память выделяется


  // <- здесь (неявно) вызывается деструктор, память освобождается
}


Добавлено через 4 минуты и 52 секунды
Цитата(Kruger2 @  11.7.2011,  15:22 Найти цитируемый пост)
Матрица у меня уже есть, зачем мне её ещё раз создавать, зачем мне функция получения значения элемента?

ок, зайдем с другого конца. 
вот зачем:
что бы разделить задачу на части, упростить её. сейчас имеешь сотню строк кода, сильно связанного между собой.
а будешь иметь ту же сотню, но в отдельных функциях, каждая - неск. строк, совершенно независимых.
допустим, структуры еще не изучал. классы тем более. давай обойдемся тем что есть.

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

Это сообщение отредактировал(а) baldina - 11.7.2011, 15:27
PM MAIL   Вверх
Kruger2
Дата 11.7.2011, 15:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Неужели нельзя в рамках моей программы выделить память, без подключения структур? Я до них ещё не добрался.
Цитата(baldina @  11.7.2011,  15:17 Найти цитируемый пост)
Цитата(Kruger2 @  11.7.2011,  14:52 )
      void inMemory(int** b);

это не вызов, а объявление


Мда, тут вызвать никак не получается 

При попытке вызвать функцию посредством

 inMemory (b) пишет   expected primary-expression before ')' token, 
что за праймери экспрешен?(
PM MAIL   Вверх
baldina
Дата 11.7.2011, 15:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



Код

int *matrix;
int size;

int get_m (int i, int j) { return matrix[i*size+j]; }
void set_m (int i, int j, int value) { matrix[i*size+j] = value; }
void create_matrix (int n) { size = n; matrix = malloc (size*size); }
void destroy_matrix () { size=0; free (matrix); }

посмотри что получилось: теперь все операции с матрицей мы можем осуществлять через эти (очень простые) функции.
можешь добавить проверки выхода индексов за границы.
можешь добавить отладочную печать.
на вызывающий код это не повлияет.

Добавлено через 1 минуту и 28 секунд
Цитата(Kruger2 @  11.7.2011,  15:35 Найти цитируемый пост)
 inMemory (b) пишет   expected primary-expression before ')' token, 

ну вообще-то у тебя в программе b определена как int, а inMemory требует int**
PM MAIL   Вверх
Kruger2
Дата 11.7.2011, 15:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



даже функцию блин вызвать не могу)
PM MAIL   Вверх
baldina
Дата 11.7.2011, 15:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



Kruger2, тут две проблемы: пока ты не очень ориентируешься в языке и стараешься решить задачу целиком. первое подтянешь, со вторым я тебе сейчас помогаю.
PM MAIL   Вверх
Kruger2
Дата 11.7.2011, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Мы будто говорим каждый сам с собойsmile Всё это прекрасно и я благодарен, но я не понимаю как мне это реализовать в рамках моего задания. Зачем там создается матрица, когда она у меня есть и так?

Меня интересует в первую очередь два вопроса. Верны ли сами функции inMemory и freeMemory и будет ли верным такой вызов?

Код

void compareLine(int i)
{
    int j;
    int** b;
    int** c;
     inMemory(b);
    for (j=0;j<SIZE;++j)
        if (A[i][j]!=A[j][i])
            return;
    printf("K=%d\n",i+1);
       freeMemory(c);
}


Добавлено через 1 минуту и 59 секунд
baldina
Да я вроде литературу читаю, простые задачи решаю, но как то ориентироваться лучше не начинаю. Хоть бери об стенку убейся, как только появляется задание выходящее за рамки того что описано в книге, я словно пытаюсь по китайски заговорить:*(

Добавлено через 6 минут и 14 секунд
Вообщем то тоже неверно, программа рушится

Добавлено через 7 минут и 59 секунд
Цитата(baldina @  11.7.2011,  15:26 Найти цитируемый пост)
я предлагаю использовать одномерный массив для матрицы

Но у меня то двумерная матрица

Добавлено через 14 минут и 34 секунды
Ладно. Пробую разобраться:

Код

int *matrix;
int size;

int get_m (int i, int j) { return matrix[i*size+j]; }
void set_m (int i, int j, int value) { matrix[i*size+j] = value; }
void create_matrix (int n) { size = n; matrix = malloc (size*size); }
void destroy_matrix () { size=0; free (matrix); }


get_m помоему все таки лишняя, разве нет? у меня ведь объявлена матрица, получается я работаю не с ней, а с той что тут будет создана
void_st //функция установки значения элемента, вообще не понимаю что за установка значения. мы же не рандомную матрицу создаем.
create matrix создает одномерный массив, тут кажись вся моя функция с проверкой должна подходить, нет? 
Код

 Array = (int **)malloc(SIZE*sizeof(int* ));
         if(!Array) 
     {
       printf("Memory not allocated. \n");
      return;
     }
     int i;
     for (i=0; i< SIZE; i++)
     {
       Array[i]= (int *) malloc(SIZE*sizeof (int ));
       if (!Array[i])
       {
         printf("Memory not allocated2 \n");
         return;
       }
     }


а destroy_matrix вроде как должна подходить моя же функция?
PM MAIL   Вверх
baldina
Дата 11.7.2011, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



Цитата(Kruger2 @  11.7.2011,  15:44 Найти цитируемый пост)
моя функция с проверкой должна подходить

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

по порядку.
1. что такое многомерный массив в С/С++? это одномерный массив, строки которого расположены последовательно в памяти (ничего необычного, ведь компьютерная память одномерная). Именно такое расположение я и предлагаю. Это проще для восприятия, чем "массив массивов".
2. неважно, что как расположено. мы пользуемся определенным интерфейсом - функциями create, get, set... Этот подход нам позволяет в процессе решения конкретной задачи не вникать в устройство массива, а в процессе проектирования интерфейсных функций не думать о всей задаче. поэтому get_m не лишняя. технически можно без нее обойтись, можно вообще все написать в единственной функции и в одну строчку, но с точки зрения грамотного проектирования и удобства использования она нужна.
3. 
Цитата(Kruger2 @  11.7.2011,  15:44 Найти цитируемый пост)
кажись вся моя функция с проверкой должна подходить

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

void inMemory (int** Array)
{
Array = (int **)malloc(SIZE*sizeof(int* ));
         if(!Array) 
     {
       printf("Memory not allocated. \n");
      return;
     }
     int i;
     for (i=0; i< SIZE; i++)
     {
       Array[i]= (int *) malloc(SIZE*sizeof (int ));
       if (!Array[i])
       {
         printf("Memory not allocated2 \n");
         return;
       }
     }

здесь есть две основные проблемы
1. параметры в С/С++ передаются по значению, поэтому если нужно инициализировать int**, то передавать приходится int***
Код

void inMemory (int*** Array)
{
  *Array = (int **)malloc(SIZE*sizeof(int* ));
  ...

2. К выделенному таким образом массиву нельзя обращаться A[i][j], т.к. элементы массива теперь не расположены последовательно.
нужно так: (A[i])[j];
уже не так красиво, как раньше, правда?  

PM MAIL   Вверх
Kruger2
Дата 11.7.2011, 16:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Всё равно ни черта не понимаю. Пойду ещё искать литературу.

Добавлено через 7 минут и 24 секунды
Вот я копировал отсюда, немнго меняя под себя. получается тут неправильный код выложили?)

Код

/*   allocate2D
/*   function to dynamically allocate 2-dimensional array using malloc.
/*
/*   accepts an int** as the "array" to be allocated, and the number of rows and
/*   columns.
*/
void allocate2D(int** array, int nrows, int ncols) {
     
     /*  allocate array of pointers  */
     array = ( int** )malloc( nrows*sizeof( int* ) );
     
     /*  allocate each row  */
     int i;
     for(i = 0; i < nrows; i++) {
          array[i] = ( int* )malloc( ncols*sizeof( int ) );
     }

}

/*   deallocate2D
/*   corresponding function to dynamically deallocate 2-dimensional array using 
/*   malloc.
/*
/*   accepts an int** as the "array" to be allocated, and the number of rows.  
/*   as with all dynamic memory allocation, failure to free malloc'ed memory
/*   will result in memory leaks
*/
void deallocate2D(int** array, int nrows) {
     
     /*  deallocate each row  */
     int i;
     for(i = 0; i < nrows; i++) {
          free(array[i]);
     }
     
     /*  deallocate array of pointers  */
     free(array);
     
}

/*   EXAMPLE USAGE:    
int** array1;

allocate2D(array1,1000,1000); //allocates a 1000x1000 array of ints

deallocate2D(array1,1000);    //deallocates the same array
*/

PM MAIL   Вверх
baldina
Дата 11.7.2011, 17:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



Kruger2, есть простой выход. вообще он не очень хороший, но в данном случае наверно лучший.
сделай 
Код

  int (*A)[SIZE];
  A = (int (*)[SIZE])malloc (SIZE*SIZE);
и обращайся A[i][j] Более сложное попробуешь, когда почитаешь
PM MAIL   Вверх
Kruger2
Дата 11.7.2011, 17:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



Код

void inMemory (int (*Array)[SIZE])
{
    
         Array = (int (*)[SIZE])malloc(SIZE*SIZE);
         if(!Array) 
     {
       printf("Memory not allocated. \n");
      return;
     }
    }



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


Бывалый
*


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

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



Цитата(Kruger2 @  11.7.2011,  14:35 Найти цитируемый пост)
Т.е. мне надо вызвать функцию малок внутри каждой из моих двух функций или вызвать её в мейне перед выполнением двух других функций?

Во первых вы ни как не используете эту память, по-этому я не могу сказать где вам надо. В данном случае правильный ответ: "нигде ни выделять ни освобождать".

Во вторых у вас все неправильно. Давайте прочитаем по русски этот код:
Код

      int b, c;
      void inMemory(int** b);
....
      void freeMemory(int** c);

обявляем две переменные типа int.
пытаемся объявить (не вызвать) функцию, которая в качестве аргумента принимает указатель на указатель на переменную типа int
пытаемся объявить (не вызвать) функцию, которая в качестве аргумента принимает указатель на указатель на переменную типа int

Все не более.
Отбрасываем ошибку, с попыткой объявить функцию
Код

      int b, c;
      inMemory(b);
....
      freeMemory(c);

Опять не увязка:
1 ваша процедура ждет указатель на указатуль......
2 Места для переменных типа int уже зарезервированы, и нет смысла выделять память (а еслибы все же нужно было то надо было писать "&b"
Правим
Код

      int **b, **c;
      inMemory(b);
....
      freeMemory(c);

Теперь все, вроде так. Но! Вызывая inMemory(b) ; вы в конечном итоге инициализируете переменную b, адресом массива указателй
переменная c при этом неинициализирована! А вы хотите освободить память по адресу хранящемуся в этой переменной!!! Ноона ни чего не содержит!
Еще раз правим.
Код

      int **b = NULL;
      inMemory(b);
....
      freeMemory(b);


Вот теперь вы память выделили, а потом освободили. Осталось придумать зачем она вам тут сдалась... В данной задаче единственное применение для этих функций. Зарезервировать место под матрицу; заполнить ее программно (сейчас у нас это константа); найти решение; освободить память.. Т.е. по сути, это должно быть в main


Цитата(Kruger2 @  11.7.2011,  14:35 Найти цитируемый пост)
и получается освобождать память тоже не надо, т.к. нет глобальных переменных ?

Если вы где то зарезервировали память, то вы обязаны ее освободить - иначе "утечка памяти". То, о чем я вам говори касается лишь освобождения памяти под автоматическую переменную хранящую адрес выделенной вами памяти.

Это сообщение отредактировал(а) voral - 11.7.2011, 17:34
PM MAIL WWW   Вверх
baldina
Дата 11.7.2011, 17:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



Цитата(Kruger2 @  11.7.2011,  16:57 Найти цитируемый пост)
получается тут неправильный код выложили?)

смотрите сами: http://codepad.org/KAP0hVsz
PM MAIL   Вверх
Kruger2
Дата 11.7.2011, 17:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


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

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



voral

Код

int main()
{
    int i;
    int **b = NULL;
    
    inMemory(b);
    for (i=0;i<SIZE;++i)
    {
        compareLine(i);
        sum(i);
    }
    freeMemory(b);
system("pause");
return 0;
}


При вызове функции freeMemory программа рушится.

Добавлено через 1 минуту и 29 секунд
baldina
Посмотрел, код рабочий. Следовательно у меня вызов кривой.

Добавлено через 2 минуты и 28 секунд
Но нет освобождения памяти. И в примере выше при попытке высвободить память программа рушится.
PM MAIL   Вверх
voral
Дата 11.7.2011, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



На всякий случай
Код

{
       int i; // объявляется переменная i, для нее резервируется память размером sizeof(int)
       int *j; //обявляется переменная j, являющаяся указателем на область памяти содержащую int. Размер выделяемой памяти sizeof(*int)
       j = (int*)malloc(4*sizeof(int)); //выделяем память под массив, адрес заносим в j  Размер выделяемой памяти 4*sizeof(*int)
} // вот достиги онца области видимости переменных i и j
// вышли из блока - осободилась память, занимаемая переменными i (sizeof(int)) и j (sizeof(*int)), но память выделенная нами mallocом  4*sizeof(*int) осталась  зарезерированной. И мы не знаем ее адреса, и уже не сможем осовободить.... Это утечка - что плохо.
Прогнать этот блок Nцать раз и вся оперативка, а потом и своп будут съедены 

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


Шустрый
*


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

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



Самое обидное что в книге кернигана и ричи 2 строки по динамическому распределению памяти, а у харви дейтела "как програмировать на си" вообще ничего)

Судя по содержанию вспоминают они о нем только в структурах
PM MAIL   Вверх
baldina
Дата 11.7.2011, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



Цитата(Kruger2 @  11.7.2011,  17:47 Найти цитируемый пост)
Посмотрел, код рабочий. 

плохо смотрели. не годный код.
PM MAIL   Вверх
voral
Дата 11.7.2011, 18:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



тут и я немного прощелкал. Дело в том как передан параметр в inMemory. Пока сам руками не написал не осознал smile. Объяснять времени не осталось, вот то что я написал
Код

#include <stdio.h>
#include <stdlib.h>
#define SIZE 3
int**  inMemory ()
{
    int** Array = (int**)malloc(SIZE*sizeof(int*));
    if(!Array)
    {
        printf("Memory not allocated. \n");
        return 0;
    }
    int i;
    for (i=0; i< SIZE; i++)
    {
        Array[i]= (int *) malloc(SIZE*sizeof (int )+1);
        if (!Array[i])
        {
            printf("Memory not allocated2 \n");
            return 0;
        }
    }
    return Array;
}
void freeMemory(int** Array)
{
    int i;
    for(i=0; i<SIZE; i++)
        free (Array[i]);
    free(Array);
}

int main()
{
    int **b = inMemory();
    if (inMemory(&b)==0) return 1;
    freeMemory(b);
    return 0;
}


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


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

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



Цитата(voral @  11.7.2011,  18:11 Найти цитируемый пост)
SIZE*sizeof (int )+1

зачем +1
?
PM MAIL   Вверх
voral
Дата 11.7.2011, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(baldina @ 11.7.2011,  18:34)
Цитата(voral @  11.7.2011,  18:11 Найти цитируемый пост)
SIZE*sizeof (int )+1

зачем +1
?

Посыпаю голову пеплом - набацал  в спешке. Тут, естественно, это совершенно не нужно. smile
PM MAIL WWW   Вверх
voral
Дата 11.7.2011, 23:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Итак, почему не работало  варианте с фунцнкцией 
Код

InMemory(int **Array)

Это вроде как раз у Кернигана нормально расписано. Параметры функции являются локальными переменными в этой функции. Т.е. в данном случае мы скоипировали значение переменной b в функции main в переменную Array функции inMemory. (т.е. NULL).
Далее этой локальной переменной присвоили значение адреса выделеной malloc памяти и вышли из функции. Но этот адрес выделенной памяти не передался обратно в процедуру main. и b так и осталась равна NULL. Демонтрирую (количество звездочек снизил, чтоб не мешались)
Код

#include <stdio.h>
#include <stdlib.h>
void inMemory (int **A)
{
    A = (int**)malloc(sizeof(int*));
    printf("In: %d\n",A);
}
int main()
{
    int **b = NULL;
    printf("Before: %d\n",b);
    inMemory(b);
    printf("After: %d\n",b);
    free(b);
    return 0;
}

Вывод:
Цитата

Before: 0
In: 85499968                                                                                                                  
After: 0    

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

#include <stdio.h>
#include <stdlib.h>
void inMemory (int ***A)
{
    *A = (int**)malloc(sizeof(int*));
    printf("In: %d\n",*A);
}
int main()
{
    int **b = NULL;
    printf("Before: %d\n",b);
    inMemory(&b);
    printf("After: %d\n",b);
    free(b);
    return 0;
}

вывод:
Цитата

Before: 0
In: 85499968
After: 85499968


Кстати до кучи.
Наглядное пояснение, а можно ли не освобождать память. В примере выше убираю строку free(b). И натравливаю на бинарник утилиту для определения утечек valgrind
Цитата

==6629== HEAP SUMMARY:
==6629==     in use at exit: 8 bytes in 1 blocks 
==6629==   total heap usage: 1 allocs, 0 frees, 8 bytes allocated
==6629== 
==6629== LEAK SUMMARY:
==6629==    definitely lost: 8 bytes in 1 blocks


в использовании нпри выходе 8 байт в одном блоке
был один аллок,  0 освобождений, 8 байт занято - это и есть вредная утечка памяти

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


Шустрый
*


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

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



Спасибо. Почитаю ещё литературу, потом буду дальше вас мучитьsmile
PM MAIL   Вверх
krot100500
Дата 27.12.2011, 00:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Всем привет!)
Благодоря этой темке я слегка разобрался в указателях) за это вам почет и уважуха)
Вообщем попал сюда как получил задание на курсач(такое-же как и у автора)
ну вообщем вот мой код для массива 3 на3 можете сказать что тут не так плиз) я подозреваю что что-то с выводом функции, голову уже сломал всю
Код

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

void out()
{
int i,j;
 int **a;
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();
    subzero(a);
    comp(a);
    getch();
    return 0;
}



Добавлено через 4 минуты и 20 секунд
Цитата(voral @  30.6.2011,  18:40 Найти цитируемый пост)
void compareLine(int i)
{
    int j;
    for (j=0;j<SIZE;++j)
        if (A[i][j]!=A[j][i])
            return;
    printf("K=%d\n",i+1);
}

зачем тут операнд return?
PM MAIL   Вверх
voral
Дата 27.12.2011, 09:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(krot100500 @  27.12.2011,  00:11 Найти цитируемый пост)
зачем тут операнд return? 

Хм... А это разве я писал?
Впрочем очевидно: Это функция проверки условия задачи. Если элемент A[i][j] не равен A[j][i] значит желаемое условие нарушено и дальнейшая проверка элементов не нужна. Следовательно выходим из функции.
PM MAIL WWW   Вверх
voral
Дата 27.12.2011, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(krot100500 @  27.12.2011,  00:11 Найти цитируемый пост)
ну вообщем вот мой код для массива 3 на3 можете сказать что тут не так плиз)

Форматирование кода - неуд.
Строка 13: Зачем?
Строка 32: Что делает?
Строка 51: в этой области видимости есть переменная. Память под массив не выделена и массив не заполнен. Этот массив в этой функции не имеет ни какого отношение к массиву в функции input


Больше пока не смотрел.....

Добавлено @ 10:34
В догонку массив a в функции input не имеет отношения к массиву a в функции main.

Добавлено @ 10:36
А так же в конце программы не освобождается память.

Это сообщение отредактировал(а) voral - 27.12.2011, 10:52
PM MAIL WWW   Вверх
voral
Дата 27.12.2011, 11:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



кстати. Небольшой "секрет". Цикл в 10 строке тоже ни чего не делает.... Вообще. Если отключить оптимизацию просто посчитает до 3. Но ни чего не сделает из того, что вы ожидаете
PM MAIL WWW   Вверх
krot100500
Дата 27.12.2011, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



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

Добавлено через 5 минут и 54 секунды
в исходники из методички я особо не разбирался просто коррекция под свой вариант) динамическое распределение памяти для меня лес темный(( примерно понял операнд малок( по Герберту Шилдту)
но там не было сказано про освобождение памяти я об этом узнал тока тут)
ЗЫ Voral свой код всегда узнать можно)) я взял твой код для статического распределения попытался в нем разобраться) вроде как понял что-то) непонял тока почему цикл тока для J есть (в comparline)

Добавлено через 10 минут и 51 секунду
ну вообщем как я понял из лекций прога в кратце будет иметь вид
#include тут все необходимые библиотеки
input{ввод масива с клавы}
comp{кстрока=кстолбцу}
subzero{вычисление суммы с отриц элементом}
out{вывод на экран}
main{в нем как раз обрашение на функции }

PM MAIL   Вверх
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   Вверх
krot100500
Дата 4.1.2012, 16:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



урра мне дали еще времени)ЗЫ я увидел свои ошибки)
вот исправил ошибки) сделал так что функции комп и сум работали с массивом)
мояя ошибка была как раз в том что надо-было указать в параметрах не цикл а указатель на функцию ввода массива, и соответственно слегка подправить эти функции 
Код

#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+1,j+1);
        scanf("%d",&a[i][j]);
    }
    }
    return a;
}
void comp(int **a)
{int j,i, raz=0;
 for( i=0;i<SIZE;++i)
 {for (j=0;j<SIZE;++j)
  {if (a[i][j]!=a[j][i]);
   else raz+=1;
    if (raz==SIZE)
    printf("sovpadeni'a v %d stroke i stolbce\n",i+1);
    }
    raz=0;
    }}
void sum(int **a)
{   int i,j, result=0, fex=0;
    for (i=0;i<SIZE;++i)
    {for (j=0;j<SIZE;++j)
    {result+=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,result);
    result=0;fex=0;
    }}
   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);
    comp(a);
    sum(a);
    int i;
    for(i=0; i<SIZE; ++i)
    {
      free(a[i]);
    }
    free(a);
    getch();
    return 0;
}


ЗЫ Кернигана и Ричи прочитал всего, но непонял)
Понял тока когда прочитал Шилдта и потыкался в тексте проги)

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


Бывалый
*


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

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



В строках 30 и 31. Что за наворот:
Код

if (a[i][j]!=a[j][i]);
   else raz+=1;

Возможно будет короче:
Код

if (a[i][j]==a[j][i])
   raz+=1;


Цитата(krot100500 @  4.1.2012,  16:43 Найти цитируемый пост)
ЗЫ Кернигана и Ричи прочитал всего, но непонял)

Так надо не на скорость и объем читать. Пока что то не понял не читаешь следующую главу. А разбираешься/читаешь непонятную до просветления.

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


Новичок



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

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



тоже вариант)но я как востпринял так и написал)
ЗЫ теперь похоже на истину?
и кстате спомощью ф-ии
Код

a=(int**)malloc(SIZE*sizeof(int*));

мы выделяем память под указатели на элементы массива так?
а
Код

a[i]=(int*)malloc(SIZE*sizeof(int));

выделяет память под сами элементы массива?

Добавлено через 1 минуту и 20 секунд
Цитата(voral @  4.1.2012,  17:14 Найти цитируемый пост)
Так надо не на скорость и объем читать. Пока что то не понял не читаешь следующую главу. А разбираешься/читаешь непонятную до просветления.

мне просто более понятно языком Шилдт'a *)
PM MAIL   Вверх
voral
Дата 9.1.2012, 16:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



Цитата(krot100500 @  4.1.2012,  21:43 Найти цитируемый пост)
и кстате спомощью ф-ии
Выделить всёкод C++
....
мы выделяем память под указатели на элементы массива так?
....
выделяет память под сами элементы массива?


Как ни странно в обоих случаях выделяем память под элементы массива. 
Но!
В первом случае элементы массива - это указатели на одномерные массивы.
Во втором случае - это значения типа int. 
 
По сути дела "двумерный" массив используемый в коде представляет из себя SIZE массивов элементов типа int (имеющих SIZE элементов). Плюс один массив элементов типа int* т.е. указателей  на те самые массивы int (имеющий SIZE элементов).


Естественно элементы массива о котором говориться непосредственно в задаче (т.е. не "вспомогательный" массив) хранятся только в памяти выделемой строкой которая приведена во второй цитате.

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


Новичок



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

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



У меня вот и возникал вопрос) зачем нам нужна динамика если известно количество элементов*)
PM MAIL   Вверх
voral
Дата 11.1.2012, 11:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



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


Новичок



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

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



ну так мы используем динамику когда, как правило неизвестно кол-во элементов) а тут задано что 8 на 8 ) и соответсвенно будет выделяться памяти под 64элемента типа инт

Добавлено через 5 минут и 15 секунд
*изначально неизвестно, и задается уже во время запуска.
PM MAIL   Вверх
voral
Дата 11.1.2012, 15:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


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

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



учебные задачи не в счет ;)
Точнее смотря, что изучаете разбирая данную задачу. Если динамические массивы сгодится, если циклы то можно и избавиться от динамического выделения.
PM MAIL WWW   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

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

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

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

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


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

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


 




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


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

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