#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» — хороший начальный запрос.