2017-01-11 2 views
0

У меня есть массив, который содержит указатели на другие массивы. Я хочу напечатать все значения, но я не могу получить sizeof конкретного массива. Что я делаю не так?Как определить размер массива в C с помощью указателей?

int main(void){ 
    int i, j; 
    float T1[4]={1.1, 1.2, 1.3, 1.4}; 
    float T2[6]={2.1, 2.2, 2.3, 2.4, 2.5, 2.6}; 
    float T3[3]={3.1, 3.2, 3.3}; 
    float T4[2]={4.1, 4.2}; 
    float T5[4]={5.1, 5.2, 5.3, 5.4}; 

    float *TAB[5]={T1, T2, T3, T4, T5}; 
    for(i=0; i<5; i++){ 
     for(j=0; j<sizeof(TAB[i])/(sizeof (int)); j++){ 
      printf("%f ", *(TAB[i]+j)); 
     } 
    } 
    printf("\n"); 
} 
+0

Указатель не является массивом! – Olaf

ответ

7

Вы не можете. Как только массив распался на указатель, у вас больше нет информации о размере массива. Вы должны отслеживать это по-другому.

В вашем случае с указанным кодом у вас может быть второй массив TAB_SIZES, который содержит размеры массивов, на которые указывает TAB.


помнить также, что для любого массива или указатель p и индекс i выражение p[i] равно *(p + i). Это означает, что вам не нужно делать *(TAB[i]+j). Вместо этого сделайте TAB[i][j], который чувствует себя более «естественным» для большинства людей.

+0

Первые два предложения сказали мне все. Я вижу, что динамическая часть этого языка сильно отличается от моей картины. – soommy12

1

При использовании в массиве sizeof возвращает количество элементов в этом массиве, умноженное на размер каждого массива, как вы можете видеть ниже.

int a[10]; 
sizeof(a); /* returns (sizeof(int) * 10) */ 

См. here для примера этого кода на работе.

Однако, когда вы назначаете T1, T2, T3, T4 и T5 в качестве элементов TAB, они преобразуются в float *, а информация о них, являющаяся массивом, отсутствует в TAB. Следовательно, когда sizeof вызывается с аргументом TAB [i], он интерпретируется только как указатель на float, и возвращается sizeof (float *).

0

Вы должны отслеживать это самостоятельно. в НКУ, следовать расширение поддерживается:

struct sized_array { 
    int size; 
    float array[0]; 
} 

это называется нулевой длины массива. и это, как вы выделяете память:

int target_size = 100; 
struct sized_array *the_array = malloc(sizeof(struct sized_array) + target_size * sizeof(float)); 
the_array->size = target_size; 

и the_array автоматически содержит массив с (по крайней мере) 100 флоат слотов. более подробную информацию вы можете получить по адресу info gcc, 6.17.

+0

Не используйте расширения компилятора, если существуют одинаковые стандартные способы. Документация gcc сама отмечает, что это устарело в forvour стандартного FAM. И это не отвечает на вопрос. – Olaf

+0

@Olaf my gcc doc указывает на отсутствие устаревания массива нулевой длины. Фактически, он уточняет разницу между zla и fam, а последняя, ​​например, не имеет полного типа. какая у вас версия документации? – HuStmpHrrr

+0

По крайней мере, начиная с 4.9.3, в нем говорится: «В ISO C99, ** вы должны использовать ** гибкий элемент массива, который немного отличается по синтаксису и семантике:« (C99 должен читать «C99 и новее» на самом деле, они имеют не изменил это предложение с первого появления). Я не намерен углубляться, но я знаю, что это тоже было в 4.6. если вы используете более старый компилятор, чем 4.9.3, вы обязательно должны обновиться. Различная семантика не имеет значения, но делает ее более правильной для использования. Например, ваш массив нулевой длины вызывает UB. Обратите внимание, что стандарт C - это C11. – Olaf

Смежные вопросы