2016-09-01 10 views
8

Я видел этот вопрос о результате sizeof(), и я не понял выход этой функции.Функция с указателем на указатель на

#include <stdio.h> 
void checkSizes(char matrix3d[10][20][30]) 
{ 
    printf ("%lu\t", sizeof(matrix3d)); 
    printf ("%lu\t", sizeof(*matrix3d)); 
    printf ("%lu\t", sizeof(**matrix3d)); 
    printf ("%lu\t", sizeof(***matrix3d)); 
} 
int main() 
{ 
    char matrix[10][20][30]; 
    checkSizes(matrix); 
} 

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

printf ("%lu\n", sizeof(matrix3d)); 

выход будет be 8.

BUT не следующий printf получит меня к другому указателю указателя, что его размер будет также 8?

так я thouth это приведет к

8 8 8 1 

реальный выход

8 600 30 1 
+2

использовать '% zu' для печати значения аргумента' sizeof' –

+6

matrix3d ​​не 'char ***', а 'char (*) [20] [30]'. Только внешний размер распадается на указатель. Остальные остаются запеченными в типе. – StoryTeller

+0

Вы можете преобразовать размер в unsigned long. 'printf ("% lu \ n ", (unsigned long) sizeof (matrix3d));' –

ответ

2

В этом заявлении

printf ("%lu\t", sizeof(*matrix3d)); 
// it is better to use "%zu\t" 

выражение *matrix3d имеет тип char[20][30].

Использование массива в операторе sizeof в качестве выражения не преобразует выражение в указатель на первый элемент массива.

Таким образом, вы получите выход 600.

Однако, если бы вы написать

sizeof(*matrix3d + 0) 

тогда действительно *matrix3d того типа char[20][30] будет конвертирована в выражении *matrix3d + 0 неявно указатель типа char (*)[30] и соответствующего printf заявление будет выводить 8,

Что касается параметр функции и его аргумент, то они неявно преобразуются в тип char (*)[20][30]

Так, например, эти объявления функций эквивалентны

void checkSizes(char matrix3d[10][20][30]); 
void checkSizes(char (*matrix3d)[20][30]); 

и объявить одну и ту же функцию.

0

Первый, как вы сказали, размер указателя, поэтому 8; последний - размер символа, поэтому 1; второй - sizeof (char) * 30 * 20, потому что вы разыменовали первое «измерение» массива, поэтому вы смотрите на то, что содержится в одном из 10 элементов этого измерения. Третий - sizeof (char) * 30, потому что вы смотрите внутри элемента второго измерения.

1

Прежде всего вам нужно знать, что sizeof является оператором, а не функцией. Массивы не преобразуются в указатель на свой первый элемент, если это операнд sizeof или унарный оператор &.

В функции checkSizes, параметр matrix3d имеет тип указатель на массив из 20 массивов 30 char с.Поскольку это указатель, заявление

printf ("%lu\t", sizeof(matrix3d)); 

напечатает размер указателя.
Выделение указателя matrix3d даст свой первый элемент. Его первым элементом является массив из 20 массивов 30 char s. sizeof(*matrix3d) вернет размер массива char[20][30], который составляет 600 байт. sizeof(*matrix3d) эквивалентно sizeof(matrix3d[0]).

Тип **matrix3d является массив 30 char с, sizeof(**matrix3d) будет печатать 30 байт.
Тип ***matrix3d is a char, sizeof(***matrix3d) напечатает 1 байт.