Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Передача двумерного массива в функцию

15K
12 августа 2008 года
like-nix
46 / / 27.06.2007
В умной книжке Искуство программирования на Си прочитал что заполнять массивы можно примерно следующим образом
Код:
void PopulateLoadingArray(double **Loading,
                         size_t MaxAge,
                         size_t NumGenders)
{
  size_t Age, Gender;

  for(Age = 0; Age < MaxAge; Age++)
  {
    for(Gender = 0; Gender < NumGenders; Gender++)
   
      **(Loading + Age * MaxAge + Gender) =
         CalcLoading(Age, Gender);
    }
  }
}


Первое что меня смущает это строка вычисления адреса элементов массива
**(Loading + Age * MaxAge + Gender)
мне кажется что строка должна быть
**(Loading + Age * NumGenders + Gender)
Если я не прав объясните пож. почему это должно работать

Второе мне не удалось программу заставить работать

полный код

Код:
#include <sys/types.h>
#include <stdio.h>

#define MAX_AGE 130
#define NUM_GENDERS 2
void PopulateLoadingArrayP(double **Loading, size_t MaxAge, size_t NumGenders)
{
  size_t Age, Gender;

  for(Age = 0; Age < MaxAge; Age++)
  {
    for(Gender = 0; Gender < NumGenders; Gender++)
      **(Loading + Age * MaxAge + Gender) = Age + Gender;
  }
}

int main()
{
  double Loading[MAX_AGE][NUM_GENDERS] = {0};
PopulateLoadingArrayP(Loading, 130, 2);
  return 0;
}


При компиляции получаю

passing argument 1 of ‘PopulateLoadingArrayP’ from incompatible pointer type

А при запуске
Segmentation fault (core dumped)

ОС Linux
Компилятор gcc
15K
12 августа 2008 года
like-nix
46 / / 27.06.2007
Рушится на строке
**(Loading + Age * MaxAge + Gender) = Age + Gender;
1.9K
12 августа 2008 года
max_dark
256 / / 11.11.2005
Во первых, функцию можно переписать так
 
Код:
void PopulateLoadingArrayP(double **Loading, size_t MaxAge, size_t NumGenders) {
  size_t Age, Gender;

  for(Age = 0; Age < MaxAge; Age++) {
    for(Gender = 0; Gender < NumGenders; Gender++)
      Loading [Age][Gender] = Age + Gender;
  }
}
Про Segmentation fault. Сам как то столкнулся со сбросом коры на подобном коде )
Проблема, как я понял, в том что double** это указатель на массив указателей, которые в свою очередь указывают на совершенно разные области памяти, в то время как
double Loading[MAX_AGE][NUM_GENDERS] представляет собой сплошную область
15K
12 августа 2008 года
like-nix
46 / / 27.06.2007
Цитата: max_dark
Во первых, функцию можно переписать так



Да это я знаю это в книжке дальше по тексту было))

В отладчике gdb я посмотрел на что **Loading указывает на не выделенную память
А выделенная память лежит по *Loading

И переписал функцию примерно так

Код:
#include <sys/types.h>
#include <stdio.h>

#define MAX_AGE 130
#define NUM_GENDERS 2
void PopulateLoadingArrayP(int **Loading, size_t MaxAge, size_t NumGenders)
{
  size_t Age, Gender;

  for(Age = 0; Age < MaxAge; Age++)
  {
    for(Gender = 0; Gender < NumGenders; Gender++)
      *(Loading + Age * NumGenders + Gender) = 5;
  }
}

int main()
{
  int Loading[MAX_AGE][NUM_GENDERS] = {0};
  PopulateLoadingArrayP(Loading, 130, 2);
  return 0;
}


Так работает но компилится с предупреждением
warning: passing argument 1 of ‘PopulateLoadingArrayP’ from incompatible pointer type
на строке PopulateLoadingArrayP(Loading, 130, 2);
15K
12 августа 2008 года
like-nix
46 / / 27.06.2007
Можно еще вот так

Код:
void PopulateLoadingArray(double Loading[][NUM_GENDERS],
                         int MaxAge,
                         int NumGenders)
{
  size_t Age, Gender;

  for(Age = 0; Age < MaxAge; Age++)
  {
    for(Gender = 0; Gender < NumGenders; Gender++){
      Loading[Age][Gender] = Age + Gender;
    }
  }
}
1.9K
12 августа 2008 года
max_dark
256 / / 11.11.2005
Но, ИМХО, лучше так:
Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TYPE int
#define MAX_AGE 130
#define NUM_GENDERS 2

TYPE* new_array(size_t N) {
    return (TYPE*)calloc(N,sizeof(TYPE));
}
TYPE** new_array2d(size_t N,size_t M) {
    TYPE** tmp=NULL;
    int i;
    tmp=(TYPE**)calloc(N,sizeof(TYPE*));
    if (tmp == NULL)
        return NULL;
    for(i=0; i<N; i++) {
        tmp = new_array(M);
    }
    return tmp;
}
void free_array2d(TYPE** m, size_t N) {
    int i;
    for (i=0; i<N; i++) {
        free(m);
    }
    free(m);
}
void PopulateLoadingArrayP(TYPE **Loading, size_t MaxAge, size_t NumGenders) {
    size_t Age, Gender;

    for(Age = 0; Age < MaxAge; Age++) {
        for(Gender = 0; Gender < NumGenders; Gender++)
            Loading [Age][Gender] = Age + Gender;
    }
}
int main()
{
    TYPE **Loading;
    Loading = new_array2d(MAX_AGE, NUM_GENDERS);
    if (Loading) {
        PopulateLoadingArrayP(Loading, MAX_AGE, NUM_GENDERS);
        free_array2d(Loading, MAX_AGE);
    }
    return 0;
}
69K
10 февраля 2011 года
vadox
1 / / 10.02.2011
функция заполнения двумерного массива
Код:
#include <iostream>
using namespace std;

void randmass(int ** mass, int rows, int cols)
{
    for (int i=0; i<rows; i++){
        for (int j=0; j<cols; j++){
            mass[j]=rand()%100;
            cout << mass[j] << " ";
        }
        cout << endl;
    }
}

int main() {
    int n=5;   
        int **matrix=new int*[n];
    for (int i=0;i<n;i++) matrix=new int[n];

    randmass(matrix, n, n); //вот здесь передается указатель на указатели

        for(int i=0; i<n; i++) delete matrix;
        delete matrix;
    cin.get();
        return 0;
}
32K
10 февраля 2011 года
Rififi
54 / / 04.06.2008
через три года награда нашла героя. loooooooool.
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог