реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> sizeof(двумерный массив), то ли лыжи не едут..
demiurg_spb
сообщение Aug 25 2011, 05:32
Сообщение #1


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Код
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).

Похоже он в первом случае возвращает размер указателя. Неожиданно...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Aug 25 2011, 05:53
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Про это во всех учебниках написано. При передачи массива в функцию фактически передается указатель на массив, что вам и показывает sizeof(). Аналогично, если вы объявите массив в одном модуле, в другом модуле вы уже не будете знать его размеров.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Aug 25 2011, 06:01
Сообщение #3


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(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];
то размер будет виден.


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Aug 25 2011, 07:15
Сообщение #4


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Спасибо за комментарии!
Цитата(sergeeff @ Aug 25 2011, 09:53) *
Про это во всех учебниках написано.
Я прекрасно знаю что всегда передаётся лишь указатель на массив.
Вопрос был в другом. Привычный синтаксис взятия размера массива тут не работает, что не является очевидным.
Нужно это запомнить. Ключевая фраза тут:
Цитата(ReAl @ Aug 25 2011, 10:01) *
указатель ... таким образом описанный.

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

Так писать слишком мозг устаёт. Я то ведь хотел красиво написать и, думаю, что получилось. Единственное накололся на взятии размера.


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
ReAl
сообщение Aug 25 2011, 09:32
Сообщение #5


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(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);. Варианты записи -- это для удовольствия программиста (для читабельности).


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th July 2025 - 18:25
Рейтинг@Mail.ru


Страница сгенерированна за 0.01397 секунд с 7
ELECTRONIX ©2004-2016