Почему указатели использования? [закрытый]

Неопределенные символы для архитектуры x86_64: «_OBJC_CLASS _ $ _ xxx», на которые ссылается: objc-class-ref в yyy.o

Это обычно означает, что вы вызываете «xxx» "(это может быть каркас или класс) из класса" yyy ". Компилятор не может найти «xxx», чтобы произошла эта ошибка.

Вам нужно добавить отсутствующие файлы (в данном случае «xxx»), щелкнув правой кнопкой мыши по папке проекта в окне навигатора и коснитесь «Добавить файлы в» YourProjectName "" вариант.

Всплывающее окно откроет ваши файлы проекта в Finder. Там вы можете увидеть недостающие файлы и просто добавить их в свой проект. Не забудьте проверить флажок «Копировать предметы в случае необходимости». Удачи !!

344
задан Kevin 30 May 2013 в 09:49
поделиться

10 ответов

  • , Почему указатели использования по нормальным переменным?

Короткий ответ: не Делать.;-) Указатели должны использоваться, где Вы не можете использовать ничто больше. Это или потому что отсутствие соответствующей функциональности, пропуская типы данных или для чистой производительности. Больше ниже...

  • , Когда и где я должен использовать указатели?

Короткий ответ здесь: Где Вы не можете использовать ничто больше. В C у Вас нет поддержки сложных типов данных, таких как строка. Нет также никакого способа передать переменную "ссылкой" на функцию. Это - то, где необходимо использовать указатели. Также у Вас могут быть они для указания на фактически что-либо, связанные списки, членов структур и так далее. Но давайте не входить в это здесь.

  • , Как Вы используете указатели с массивами?

С небольшим усилием и большим количеством беспорядка.;-), Если мы говорим о простых типах данных, таких как интервал и символ, там мало различия между массивом и указателем. Эти объявления очень похожи (но не то же - например, sizeof возвратит различные значения):

char* a = "Hello";
char a[] = "Hello";

можно достигнуть любого элемента в массиве как это

printf("Second char is: %c", a[1]);

Индекс 1, так как массив запускается с элемента 0.:-)

Или Вы могли одинаково сделать это

printf("Second char is: %c", *(a+1));

, оператор указателя (*) необходим, так как мы говорим printf, что хотим распечатать символ. Без *, было бы распечатано символьное представление самого адреса памяти. Теперь мы используем сам символ вместо этого. Если бы мы использовали %s вместо %c, мы попросили бы, чтобы printf распечатал содержание адреса памяти, на который указывают плюс один (в этом примере выше), и мы не должны были помещать * впереди:

printf("Second char is: %s", (a+1)); /* WRONG */

, Но это просто не распечатало бы второй символ, но вместо этого все символы в следующих адресах памяти, пока нулевой символ (\0) не был найден. И это - то, где вещи начинают становиться опасными. Что, если Вы случайно пытаетесь распечатать переменную целого числа типа вместо символьного указателя с %s средством форматирования?

char* a = "Hello";
int b = 120;
printf("Second char is: %s", b);

Это распечатало бы то, что найдено на адресе памяти 120, и продолжите печатать, пока нулевой символ не был найден. Это неправильно и недопустимо для выполнения этого printf оператора, но это, вероятно, работало бы так или иначе, так как указатель на самом деле имеет интервал типа во многих средах. Вообразите проблемы, которые Вы могли бы вызвать, если бы необходимо было использовать sprintf () вместо этого и присвоить этот слишком долгий "массив символов" другой переменной, это только выделило определенное ограниченное пространство. Вы, скорее всего, закончили бы тем, что переписали что-то еще в памяти и заставили бы свою программу отказывать (если Вы удачливы).

, О, и если Вы не присваиваете строковое значение массиву символов / указатель, когда Вы объявляете его, НЕОБХОДИМО выделить достаточный объем памяти ему прежде, чем дать ему значение. Используя malloc, calloc или подобный. Это, так как Вы только объявили, что один элемент в Вашем массиве / один единственный адрес памяти указал на. Таким образом, вот несколько примеров:

char* x;
/* Allocate 6 bytes of memory for me and point x to the first of them. */
x = (char*) malloc(6);
x[0] = 'H';
x[1] = 'e';
x[2] = 'l';
x[3] = 'l';
x[4] = 'o';
x[5] = '\0';
printf("String \"%s\" at address: %d\n", x, x);
/* Delete the allocation (reservation) of the memory. */
/* The char pointer x is still pointing to this address in memory though! */
free(x);
/* Same as malloc but here the allocated space is filled with null characters!*/
x = (char *) calloc(6, sizeof(x));
x[0] = 'H';
x[1] = 'e';
x[2] = 'l';
x[3] = 'l';
x[4] = 'o';
x[5] = '\0';
printf("String \"%s\" at address: %d\n", x, x);
/* And delete the allocation again... */
free(x);
/* We can set the size at declaration time as well */
char xx[6];
xx[0] = 'H';
xx[1] = 'e';
xx[2] = 'l';
xx[3] = 'l';
xx[4] = 'o';
xx[5] = '\0';
printf("String \"%s\" at address: %d\n", xx, xx);

Действительно отмечают, что можно все еще использовать переменную x после выполнения свободного () выделенной памяти но Вы не знаете то, что там. Также заметьте, что два printf () могли бы дать Вам различные адреса, так как нет никакой гарантии, что второе выделение памяти выполняется в том же пространстве как первое.

170
ответ дан HiddenKnowledge 23 November 2019 в 00:31
поделиться

В Java и C# все ссылки на объект являются указателями, вещь с C++ состоит в том, что Вы имеете больше контроля на где Вы точки указателя. Помните С великой державой, прибывает главная ответственность.

3
ответ дан Marioh 23 November 2019 в 00:31
поделиться

Поскольку копирование больших объектов на всем протяжении мест напрасно тратит время и память.

5
ответ дан Andrew Medico 23 November 2019 в 00:31
поделиться

В значительной степени указатели являются массивами (в C/C++) - они - адреса в памяти и могут быть получены доступ как массив при желании (в "нормальных" случаях).

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

, Если Вы хотите сделать выделение динамической памяти (такой что касается связанного списка), необходимо использовать указатели, потому что они - единственный способ захватить память от "кучи".

10
ответ дан warren 23 November 2019 в 00:31
поделиться

Одно использование указателей (я не упомяну вещи, уже охваченные в сообщениях других людей) должно получить доступ к памяти, которую Вы не выделили. Это не полезно очень для программирования ПК, но оно используется во встроенном программировании для доступа к устройствам с отображенной памятью.

Назад в былые времена DOS, Вы раньше были в состоянии получить доступ к видеопамяти видеокарты непосредственно путем объявления указателя на:

unsigned char *pVideoMemory = (unsigned char *)0xA0000000;

Много встроенных устройств все еще используют эту технику.

12
ответ дан MrZebra 23 November 2019 в 00:31
поделиться

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

лучшее объяснение указателей и адресной арифметики с указателями, которую я считал, находится в K & R Язык программирования C . Хорошая книга для начала, изучая C++ Краткая информация .

C++
26
ответ дан Bill the Lizard 23 November 2019 в 00:31
поделиться

Вот немного отличающееся, но проницательный берут на себя, почему много функций C имеют смысл: http://steve.yegge.googlepages.com/tour-de-babel#C

В основном, стандартной архитектурой ЦП является Архитектура фон Неймана, и чрезвычайно полезно быть в состоянии относиться к местоположению элемента данных в памяти и сделать арифметику с ним, на такой машине. Если Вы будете знать какой-либо вариант ассемблера, Вы будете быстро видеть, насколько крайне важный это на низком уровне.

C++ делает указатели немного сбивающими с толку, так как он иногда управляет ими для Вас и скрывает их эффект в форме "ссылок". При использовании прямого C потребность в указателях намного более очевидна: нет никакого другого способа сделать вызов по ссылке, это - лучший способ сохранить строку, это - лучший способ выполнить итерации через массив, и т.д.

13
ответ дан Dan Lenski 23 November 2019 в 00:31
поделиться
  1. Указатели позволяют Вам обращаться к тому же пространству в памяти от нескольких местоположений. Это означает, что можно обновить память в одном месте, и изменение видно от другого местоположения в программе. Вы также оставите свободное место способностью совместно использовать компоненты в Ваших структурах данных.
  2. необходимо использовать указатели любое место, где необходимо получить и раздать адрес к определенному месту в памяти. Можно также использовать указатели для навигации по массивам:
  3. массив является блоком непрерывной памяти, которая была выделена с определенным типом. Название массива содержит значение стартового пятна массива. Когда Вы добавляете 1, который берет Вас к второму пятну. Это позволяет Вам писать циклы, которые увеличивают указатель, который скатывается с массива, не имея явного счетчика для использования в доступе к массиву.

Вот пример в C:

char hello[] = "hello";

char *p = hello;

while (*p)
{
    *p += 1; // increase the character by one

    p += 1; // move to the next spot
}

printf(hello);

печать

ifmmp

, потому что это принимает значение для каждого символа и увеличивает его одним.

38
ответ дан Kyle Cronin 23 November 2019 в 00:31
поделиться

Одна причина использовать указатели состоит в том так, чтобы переменная или объект могли быть изменены в вызванной функции.

В C++ это - лучшая практика для использования ссылок, чем указатели. Хотя ссылки являются по существу указателями, C++ в некоторой степени скрывает факт и заставляет его казаться, как будто Вы являетесь передающими значением. Это облегчает изменять способ, которым функция вызова получает значение, не имея необходимость изменять семантику передачи его.

Рассматривают следующие примеры:

Используя ссылки:

public void doSomething()
{
    int i = 10;
    doSomethingElse(i);  // passes i by references since doSomethingElse() receives it
                         // by reference, but the syntax makes it appear as if i is passed
                         // by value
}

public void doSomethingElse(int& i)  // receives i as a reference
{
    cout << i << endl;
}

Используя указатели:

public void doSomething()
{
    int i = 10;
    doSomethingElse(&i);
}

public void doSomethingElse(int* i)
{
    cout << *i << endl;
}
49
ответ дан trshiv 23 November 2019 в 00:31
поделиться

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

Указатели полезны, где Вы требуете высокопроизводительного и/или компактного объема потребляемой памяти.

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

9
ответ дан Ash 23 November 2019 в 00:31
поделиться