Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: sizeof(двумерный массив)
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
demiurg_spb
Код
void show_size(float a[3][3])
{
     printf("sizeof(a)=%d\n",sizeof(a));
}
sizeof(a)=4

Код
void show_size(void)
{
     float a[3][3];
     printf("sizeof(a)=%d\n",sizeof(a));
}
sizeof(a)=36

Это нормально? Мне казалось, что всегда должно быть 3*3*4=36...
Да, компилятор mingw32tdm (gcc-4.5.2).

Похоже он в первом случае возвращает размер указателя. Неожиданно...
sergeeff
Про это во всех учебниках написано. При передачи массива в функцию фактически передается указатель на массив, что вам и показывает sizeof(). Аналогично, если вы объявите массив в одном модуле, в другом модуле вы уже не будете знать его размеров.
ReAl
Цитата(demiurg_spb @ Aug 25 2011, 08:32) *
Похоже он в первом случае возвращает размер указателя. Неожиданно...
Так функции никогда массив не принимали, только указатель на него, просто таким образом описанный.
Прототип Вашей функции с точки зрения компилятора -- void show_size(float (*a)[3]);, т.е. функция принимает указатель на массивы float[3]

Цитата(sergeeff @ Aug 25 2011, 08:53) *
если вы объявите массив в одном модуле, в другом модуле вы уже не будете знать его размеров.
Ну это смотря как описать его в include-файле либо по месту.
Если никак, то он вообще не будет виден в других модулях.
Если
Код
extern float a[][3];
то размер массива будет неизвестен, информация только о размере подмассива.
Если
Код
extern float a[3][3];
то размер будет виден.
demiurg_spb
Спасибо за комментарии!
Цитата(sergeeff @ Aug 25 2011, 09:53) *
Про это во всех учебниках написано.
Я прекрасно знаю что всегда передаётся лишь указатель на массив.
Вопрос был в другом. Привычный синтаксис взятия размера массива тут не работает, что не является очевидным.
Нужно это запомнить. Ключевая фраза тут:
Цитата(ReAl @ Aug 25 2011, 10:01) *
указатель ... таким образом описанный.

Цитата(ReAl @ Aug 25 2011, 10:01) *
Прототип Вашей функции с точки зрения компилятора -- void show_size(float (*a)[3]);

Так писать слишком мозг устаёт. Я то ведь хотел красиво написать и, думаю, что получилось. Единственное накололся на взятии размера.
ReAl
Цитата(demiurg_spb @ Aug 25 2011, 10:15) *
Так писать слишком мозг устаёт. Я то ведь хотел красиво написать и, думаю, что получилось. Единственное накололся на взятии размера.
Всё Вы правильно написали. Я говорю о том, как этот прототип воспринят компилятором, как он заведёт переменную для аргумента и что будет использовать для проверки типов при передаче.
Т.е.
Код
void foo(int a[3][3]);
// при передаче в функцию foo
int a3_3[3][3]; // OK
int a7_3[7][3]; // OK
int (*pa3)[3];  // OK
int a7_7[7][7]; // Предупреждение о несоответствии
Более того, аргумент a в foo() вполне себя как указатель и ведёт:
Код
int foo(int a[3][3])
{
        int i;
        int sum = 0;
        // Суммируем нулевой столбец
        for(i = 0; i < 3; ++i) {
                sum += a[0][0];
                ++a; // допустимо и кроме foo(int (* const a)[3]) модификацию и не запретить
        }
        return sum;
}

Так же что void foo(int a[]);, что void foo(int a[3]); воспримет как void foo(int *a);. Варианты записи -- это для удовольствия программиста (для читабельности).
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.