Различные типы для объявления переменных указателя - PullRequest
0 голосов
/ 01 мая 2010

Рассмотрим следующие 2 объявления.

* появляется рядом с типом данных, а не рядом с переменной

char* ptr1, * ptr2, * ptr3; //all 3 are pointers

* появляется рядом с переменной, а не рядом с типом данных

char *ptr1,*ptr2,*ptr3; //again all 3 are pointers

Есть ли разница в интерпретации между двумя декларациями? Я знаю, что нет разницы в переменных.

В чем смысл введения пустых указателей?

Ответы [ 5 ]

5 голосов
/ 01 мая 2010

Единственное отличие - это пробелы, они заканчиваются указателями на символы. Я лично использую char * ptr1, используя много пробелов в моем коде.

Пустые указатели могут указывать на любой тип объекта и не иметь размера. Например, это работает (но на самом деле не очень хорошая идея):

int * ptr1;
float * ptr2;
(*ptr1) = 17;
ptr2 = (void*)ptr1;

(*ptr2) теперь будет интерпретировать байты ptr1 как число с плавающей точкой вместо int, что даст вам другой результат. Вы можете переключаться между типами. Также есть некоторые варианты использования void* s в typedefs типа указатель на функцию.

Кроме того, если у вас есть char * ptr1 и вы делаете ptr1++, вы увеличите адрес, на который ссылается ptr1, на sizeof(char). Это невозможно с void *, это даст вам ошибку компилятора, говорящую, что он не знает, на какой размер увеличивать.

1 голос
/ 01 мая 2010

Пустой указатель представляет отсутствие типа данных и, следовательно, может использоваться для указания на данные любого типа. Однако, так как тип данных неизвестен, нет способа напрямую разыменовать указатель. Для этого необходимо заранее привести указатель на определенный тип данных.

Ситуации, когда указатель недействителен: Иногда, чтобы заставить функцию принимать данные разных типов, например, int, char, double и т. д., можно использовать шаблон. (Хотя перегруженная функция - вариант, но наименее эффективный способ). Другой способ для этого - использовать указатель void.

void FunctionName (void * data, type param) { / * на основе второго аргумента param разыменяем данные указателя так, чтобы данные могут быть обработаны по желанию. * / }

Просто напоминание: Пустой указатель и нулевой указатель должны различаться, поскольку они имеют разные цели использования и функциональности. Последний имеет тип указателя, но не указывает на какой-либо действительный адрес каких-либо данных.

1 голос
/ 01 мая 2010
  1. Единственная разница в пропусках, которые не имеют значения. * не «появляется рядом с типом данных» или «рядом с переменной» - вы даже можете написать char*a,*b;. Важной вещью является приоритет. * связывается справа, поэтому с именем переменной. Это также означает, что char* a, b; эквивалентно char (*a), b; и приведет к указателю на char a и char b, а не к двум указателям. Если вам нужны два указателя, вам нужно использовать char *a, *b;, как в вашем примере.
  2. Пустой указатель - это указатель на память без указания типа. Это полезно при написании функции, которая должна принимать различные типы данных. Например, функция библиотеки c memcpy() копирует произвольные данные. Его не волнуют данные, которые он передает. Поскольку вы не знаете, какие данные будут переданы при реализации этой функции, для этого вам нужно будет использовать void*, иначе вам понадобится функция memcpy() для каждого типа данных (комбинации), который вы можете передать. Поскольку это функция библиотеки c и c не поддерживает перегрузку функций, для этого потребуется множество memcpy() функций с разными именами.
1 голос
/ 01 мая 2010

Пустые указатели являются указателями на некоторые неизвестные данные, они могут быть преобразованы к любому типу и, таким образом, не являются типобезопасными, и они могут привести к сбою вашей программы, используйте boost :: any, если есть необходимость в общем варианте.
Там нет разницы между объявлениями.

0 голосов
/ 01 мая 2010

Я слышал шутку, в которой говорится, что если вы спросите программиста на C ++, они скажут вам поставить его слева, а программиста на C - справа.

В конечном счете, поскольку * связывается с переменной, а не с именем типа, то, несомненно, лучше сделать это правильно, чтобы сделать код более понятным. Однако, поскольку в C ++ очень мало причин для работы с необработанными указателями, у меня никогда не возникало проблем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...