C размер символа * массив

У меня есть char*массив следующим образом:

char *tbl[] = { "1", "2", "3" };

Как мне использовать sizeofоператор для получения количества элементов массива, здесь 3?

Ниже работает, но правильно ли это?

int n = sizeof(tbl) / sizeof(tbl[0]) 
13.10.2009 12:33:06
Это было на самом деле ответил здесь И это был правильный способ сделать это.
Ayman 13.10.2009 12:34:54
Нет, если массив был получен в качестве параметра. Проверьте мой ответ на аналогичный вопрос .
Elideb 27.04.2012 11:16:11
Peter Mortensen 28.02.2013 16:14:08
@Elideb: Строго говоря, массив не может быть параметром. Параметр, определенный как char *tbl[]действительно, имеет тип char**; тип корректируется во время компиляции.
Keith Thompson 7.08.2013 14:57:58
@KeithThompson Да, я знаю, но я все еще нахожу код с массивами в качестве параметров, и люди ожидают, что они будут вести себя так. Я постараюсь быть более правильным, когда говорю о них.
Elideb 28.08.2013 17:37:12
3 ОТВЕТА
РЕШЕНИЕ

Да,

size_t n = sizeof(tbl) / sizeof(tbl[0])

это наиболее типичный способ сделать это.

Обратите внимание, что использование intразмеров массивов - не лучшая идея.

38
16.09.2015 06:43:28
Что-то не так с использованием size_tдля размеров? Или хоть что-то без знака?
Chris Lutz 13.10.2009 16:53:37
sizeof(char)не спасает вас от разыменования. Компилятор вычисляет размер tbl[0], понимая его тип, и фактически не генерирует для него код. Единственное , что sizeof(char)вместо того , чтобы sizeof(tbl[0])бы добиться для вас проблемой в будущем , если массив меняет свой тип с charчем - то другим.
Shahbaz 7.08.2013 14:30:18
@Shahbaz Я считаю, что как только компилятор увидит sizeofвызов для массива переменного размера, он может оптимизировать его для «умножения длины массива на размер элемента», что приведет к «почти времени компиляции» sizeof. Во время выполнения не существует вещи, называемой «массивом», и, следовательно, ее негде хранить.
aragaer 7.08.2013 14:37:18
@Shahbaz, но если мы знаем во время компиляции, что int array[n]; length = sizeof(array) / sizeof(*array);мы можем предположить это length = n;и избежать каких-либо вычислений вообще.
aragaer 7.08.2013 14:41:04
Замена sizeof(tbl[0])на sizeof(char)не является оптимизацией и не является правильной . tbl[0]это a char*, а не a charsizeof(char)1 по определению), поэтому ваша «оптимизированная» версия просто возвращает размер в байтах массива. sizeofвсегда вычисляется во время компиляции, если аргумент не является массивом переменной длины.
Keith Thompson 7.08.2013 14:51:49

Более короткая и, возможно, более чистая версия будет выглядеть как

sizeof tbl / sizeof *tbl

:)

17
13.10.2009 16:46:22
Это конечно спорно.
Justin 13.07.2013 15:31:47

Да, он даст вам количество элементов в массиве tb1.

int n = sizeof(tbl) / sizeof(tbl[0])

Интерпретация:

sizeof (tb1) даст размер всего массива, т.е. tb1 = 3 байта

sizeof (tb1 [0]) дает размер символа, так как tb1 [0] дает значение символа (значение по адресу tb1 + 0) = 1 байт

Разделение этих двух даст вам 3 элемента

4
7.08.2013 15:12:03
tblэто массив char*, а не массив char. Если sizeof (char*) == 4, тогда вы делите 12 байтов на 4 байта, получается 3 элемента массива , а не 3 байта.
Keith Thompson 7.08.2013 15:01:16
извините, это типо, должно быть 3 элемента, а не байты .. :)
Mahesh 7.08.2013 15:04:16
@tbl все еще не массив символов.
Keith Thompson 7.08.2013 15:08:07
Нет, все еще неверно. tblэто массив char*, а не массив char. Размер tbl[0]не 1 байт, если вы не в странной системе с 1-байтовыми указателями.
Keith Thompson 7.08.2013 15:14:07
но sizeof tb1 [0] дает нам размер значения, присутствующего по адресу tb1 [0], который должен быть символом справа? ...
Mahesh 7.08.2013 15:16:44