Как проверить, указывает ли указатель на массив или один int или char

#c #arrays #object #templates

#c #указатели

Вопрос:

Я хочу знать, указывает ли указатель на массив или на одно целое число. У меня есть функция, которая принимает два указателя (int и char) в качестве входных данных и сообщает, указывает ли указатель на массив или на одно целое число.

 pointer=pointer 4;
pointer1=pointer1 4;
 

Это хорошая идея?

Комментарии:

1. Для этого нет переносимого способа.

2. @Donnie, не такой уж и непереносимый способ.

3. OP: Зачем вам знать, указывает ли он на массив или на одно целое число? Какую проблему вы действительно пытаетесь решить?

4. @SergeyA вы можете иногда получать размеры выделения и пытаться угадать, основываясь на размере примитива, но да, вы все еще просто догадываетесь.

Ответ №1:

Как уже говорили здесь другие, C не знает, на что указывает указатель. Однако, если вы решите пойти по этому пути, вы можете поместить контрольное значение в целое число или в первую позицию в массиве, чтобы указать, что это такое…

 #define ARRAY_SENTINEL -1

int x = 0;
int x_array[3] = {ARRAY_SENTINEL, 7, 11};

pointer = amp;x_array[0];

if (*pointer == ARRAY_SENTINEL)
{
   // do some crazy stuff
}

pointer = amp;x;

if (*pointer != ARRAY_SENTINEL)
{
   // do some more crazy stuff
}
 

Комментарии:

1. Это работает, только если вы можете гарантировать, что один int объект, на который указывает указатель, не содержит значения -1 . (Кстати, макрос должен быть заключен в круглые скобки, и вы написали с ошибкой SENTINEL .)

2. Также вы, возможно, пропустили, что мы говорим о C , а не C.

3. 0xDEADBEEF (или аналогичный) будет гораздо лучшим sentinel, чем -1.

4. Это верно как для C, так и для C . Ни один из них не может знать, на что указывает указатель. И да, вам нужно будет придумать уникальное значение sentinel . Я не рекомендую делать то, что я сделал выше, но хотел ответить на его вопрос. Макрос в порядке.

5. Также я забыл привести сравнение «if», но поскольку author использует это для определения int по сравнению с массивом int, в этом нет необходимости.

Ответ №2:

Это не очень хорошая идея. Используя только необработанные указатели, невозможно узнать, указывают ли они на массив или на одно значение.

Указатель, который используется как массив, и указатель на отдельные значения идентичны — они оба являются просто адресом памяти — поэтому нет никакой информации, которую можно использовать для их различения. Если вы публикуете то, что хотите в конечном итоге сделать, может быть решение, которое не зависит от сравнения указателей на массивы и отдельные значения.

Комментарии:

1. Указатель не «используется как массив». Массивы и указатели — разные вещи. См. Раздел 6 часто задаваемых вопросов comp.lang.c .

2. @KeithThompson, я не согласен с вашим комментарием. Указатели не являются массивами, но указатели могут использоваться как массив. В этом ответе нет ничего плохого.

3. @SergeyA: Что именно означает «использовать указатель как массив»?

4. @KeithThompson, например, используйте оператор подстрочного индекса массива. (не говорите мне, что оператор подстрочного индекса массива можно использовать в целочисленной константе, это не главное). Указатели также могут участвовать в арифметике указателей, которая определена только для массивов.

5. @KeithThompson, тем не менее, с точки зрения непрофессионалов, это считается матерью всех видов использования массива (и в имени оператора даже есть слово array ). в нем).

Ответ №3:

На самом деле указатели указывают на часть памяти, а не на целые числа или массивы. Невозможно определить, является ли целое число единственной переменной или целое число является элементом массива, оба будут выглядеть в памяти одинаково. Можете ли вы использовать некоторые структуры данных C , например, std::vector?

Ответ №4:

На вопросы C ответ прост. Не используйте динамические массивы в стиле C в C . Всякий раз, когда вам нужен динамический массив в стиле C, вы должны использовать std::vector .

Таким образом, вы никогда не догадаетесь, на что указывает указатель, потому std::vector что будет содержать только массив.

Комментарии:

1. Я согласен с этим анонимным даунвотером. Существуют приложения, в которых динамически выделяемый массив более (слегка) эффективен и, следовательно, лучше использовать. Насколько я знаю, ‘std:: vector’ используется для динамической работы — когда вы хотите добавлять и удалять элементы непредсказуемым образом, но если вам нужно написать какой-то алгоритм, где размер массива известен и не будет меняться во время выполнения, ‘std:: vector’ полностьюперебор. Например, [ссылка] ( en.wikipedia.org/wiki/Floyd–Warshall_algorithm ).

2. Но я предполагаю, что отрицательный ответ относится к вашему оффтопическому ответу.

3. @RainbowTom, ты ошибаешься. Вектор C обеспечивает такую же или лучшую производительность по сравнению с динамическим массивом в стиле C. И я не вижу в этом оффтопика, это очень оффтопично, потому что это предлагает лучший способ сделать то же самое.

4. Можете ли вы привести мне несколько лучших аргументов? Ссылка на некоторые документы, блог и т. Д. Я студент, я хотел бы это узнать 🙂

5. @RainbowTom, начни с Google. «производительность std::vector по сравнению с массивом в стиле C» — хороший начальный запрос.