2008-10-07 4 views
57

Я недавно решил, что мне просто нужно наконец изучить C/C++, и есть одна вещь, которую я действительно не понимаю в указателях или, точнее, их определении.Размещение звездочки в объявлениях указателей

Как насчет этих примеров:

  1. int* test;
  2. int *test;
  3. int * test;
  4. int* test,test2;
  5. int *test,test2;
  6. int * test,test2;

Теперь, насколько я понимаю, первые три случая делают то же самое: Test не является int, а указателем на один.

Второй набор примеров немного сложнее. В случае 4 оба теста и test2 будут указателями на int, тогда как в случае 5 только тест является указателем, тогда как test2 является «реальным» int. Как насчет случая 6? То же, что и в случае 5?

+6

В C/C++ пробелы не меняют значения. – Sulthan 2012-09-15 16:14:30

+7

7. `int * test;`? – 2015-08-24 10:52:21

+1

+1, потому что я только думал спросить о 1 - 3. Чтение этого вопроса научило мне что-то о 4-6, о котором я никогда не думал. – vastlysuperiorman 2016-04-21 16:14:48

ответ

109

4, 5 и 6 - это то же самое, только test - указатель. Если вы хотите, два указателя, вы должны использовать:

int *test, *test2; 

Или, еще лучше (чтобы сделать все ясно):

int* test; 
int* test2; 
+1

Итак, случай 4 на самом деле является смертельной ловушкой? Есть ли какая-либо спецификация или дальнейшее чтение, объясняющее, почему int * test, test2 только делает первую переменную указателем? – 2008-10-07 21:06:30

+4

@ Michael Stum Это C++, так вы действительно думаете, что есть логическое объяснение? – 2008-10-07 21:07:53

+5

Читайте K & R (язык программирования C). Это объясняет все это очень четко. – Ferruccio 2008-10-07 21:09:09

5

В 4, 5 и 6, test всегда указатель и test2 является не указатель. Белое пространство (почти) никогда не бывает значительным в C++.

38

Белые пространства вокруг звездочек не имеют значения. Все три означают то же самое:

int* test; 
int *test; 
int * test; 

«int *var1, var2» является злом синтаксис, который просто означает, чтобы запутать людей, и их следует избегать. Он расширяется до:

int *var1; 
int var2; 
1

Указатель представляет собой модификатор типа. Лучше всего прочитать их справа налево, чтобы лучше понять, как звездочка модифицирует тип. 'int *' может быть прочитан как «указатель на int». В нескольких объявлениях вы должны указать, что каждая переменная является указателем, или она будет создана как стандартная переменная.

1,2 и 3) Тест типа (интермедиат *). пробелы не имеет значения.

4,5 и 6) Тест типа (Int *). Test2 имеет тип междунар. Опять пробельные несущественна.

25

Многие принципы кодирования рекомендуют вы только объявляете одной переменной в строке. Это позволяет избежать всякой путаницы в вашем роде, прежде чем задавать этот вопрос. Большинство программистов на С ++, с которыми я работал, похоже, придерживаются этого.


Немного в стороне, я знаю, но что-то, что мне показалось полезным, - это прочитать декларации в обратном направлении.

int* test; // test is a pointer to an int 

Это начинает работать очень хорошо, особенно, когда вы начинаете объявляя константные указатели и это становится сложнее, чтобы узнать, является ли это указатель, это сопзЬ, или его вещь указатель указывает на то есть Уст.

int* const test; // test is a const pointer to an int 

int const * test; // test is a pointer to a const int ... but many people write this as 
const int * test; // test is a pointer to an int that's const 
30

Используйте "Clockwise Spiral Rule", чтобы помочь разобрать объявления C/C++;

Есть три простых шага, чтобы следовать:

  1. Начиная с неизвестного элемента, движение по спирали по часовой стрелке/ направлении; когда ecountering следующие элементы заменить их соответствующие английские высказывания:

    [X] или []: Массив X размер ... или массив не определен размер ...

    (type1, type2): функция прохождения type1 и type2 возвращения. ..

    *: указатель (ей) ...

  2. продолжать это делать в направлении спирали/по часовой стрелке до тех пор, пока не будут охвачены все жетоны.
  3. Всегда сначала разрешайте что-либо в скобках!

Кроме того, заявления должны быть в отдельных заявлениях, когда это возможно (что справедливо подавляющее большинство раз).

0

Хорошее эмпирическое правило, многие люди, похоже, понимают эти понятия: В C++ много семантического значения вызывается левым связыванием ключевых слов или идентификаторов.

Возьмем, к примеру:

int const bla; 

Конст относится к "ИНТ" слова. То же самое со звездочками указателей, они применяются к ключевому слову слева от них. И имя фактической переменной? Да, это объявлено тем, что осталось от него.

-2

Случаи 1, 2 и 3 одинаковы, они объявляют указатели на переменные int. Случаи 3, 4 и 5 совпадают, так как они объявляют один указатель и одну переменную int соответственно. Если вы хотите сделать объявить два указатель в одной строке (которые вы не должны), нужны поставить звездочку перед каждым именем переменного:

int *test, *test2; 

Там нет определенного правильного пути, который говорит, где звездочка идет , int* test выглядит лучше, потому что нам легче представить, что добавление * в конец типа означает «указатель на» этот тип. Тем не менее, int *test имеет больше смысла, потому что вы можете работать с ним, как со знаком минус в математике:

-(-x) = x 

аналогично

*(*test) = test 

Это всегда помогало мне.К сожалению, результат всего этого заключается в том, что иногда я использую int* test, а иногда и int *test.

10

Как упоминалось выше, 4, 5 и 6 являются одинаковыми. Часто люди используют эти примеры, чтобы аргумент, который принадлежит *, вместо переменной. Хотя это вопрос стиля, есть некоторые дебаты относительно того, должны ли вы думать и писать об этом так:

int* x; // "x is a pointer to int" 

или так:

int *x; // "*x is an int" 

FWIW Я в первом лагере , но причина, другие делают аргумент для второй формы является то, что (в основном) решает эту конкретную проблему:

int* x,y; // "x is a pointer to int, y is an int" 

, который может ввести в заблуждение; вместо этого можно было бы написать либо

int *x,y; // it's a little clearer what is going on here 

или, если вы действительно хотите, два указателя,

int *x, *y; // two pointers 

Лично я говорю держать его одной переменной в каждой строке, то это не имеет значения, какой стиль вы предпочитаете.

1

Вы можете думать о 4, 5 и 6 следующим образом: Объявление типа должно выполняться только один раз, но если вы хотите объявить указатель на этот тип (добавив звездочку), вы должны сделать это для каждой переменной.

При объявлении переменной указателя я всегда добавляю пробел между переменной и звездочкой, даже если я объявляю более одного в строке. Не делая этого, я смущаю его для разыменования выражения почти каждый раз.

0

Обоснование в C состоит в том, что вы объявляете переменные так, как вы их используете. Например

char *a[100]; 

говорит, что *a[42] будет char. И a[42] указатель char. Таким образом, a представляет собой массив указателей на символы.

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

0

Я хотел бы сказать, что первоначальная конвенция поставить звезду на стороне имени указателя (правая сторону декларации

  • в С язык программирования Деннис М. Ритчи звезды на правой стороне декларации.

  • , глядя на исходный код Linux на https://github.com/torvalds/linux/blob/master/init/main.c мы можем видеть, что звезда также находится на правой стороне.

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

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

  • Нет связанных вопросов^_^