Какой смысл указателей?

Он готов к событию, когда DOM (объектная модель документа) загружена.

Поскольку это событие происходит после того, как документ готов, это хорошее место для всех других событий и функций jQuery. Как и в примере выше.

Метод ready () указывает, что происходит, когда происходит событие готовности.

Совет. Метод ready () не должен использоваться вместе с.

13
задан Smi 13 February 2015 в 17:50
поделиться

11 ответов

Указатели лучше всего понятны из-за различий C и C ++ в передаче переменных функциям.

Да, вы можете передавать либо целую переменную, либо просто указатель на нее (жаргон - это значение или ссылка соответственно).

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

Лучше просто " указать "на это. Вы говорите: «вот указатель на большой кусок памяти». И это небольшое косвенное обращение экономит массу времени.

Как только вы это поймете, все остальное в основном останется таким же.

30
ответ дан 1 December 2019 в 17:51
поделиться

На самом базовом уровне указатели позволяют связывать непересекающиеся блоки памяти. Простым (по общему признанию, надуманным) примером того, как указатели могут вам помочь, был бы алгоритм, который требует массива из 1000000000000 целых чисел. Такой массив был бы слишком большим, чтобы поместиться в ОЗУ машины, на которой я сейчас печатаю, если бы я попробовал такое определение, как:

int bigMatrix[1000000000000]; // I can't allocate this much contiguous memory

Однако, если я создам единственный массив указателей, я могу сохранить под- массивы на дисковом массиве среднего размера.

int *bigMatrix[1000000]; // Each pointer refers to a sub-array 
                         // of 1000000 elements on disk

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

1
ответ дан 1 December 2019 в 17:51
поделиться

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

bool ReadDataFromFile(char** contents);

Вы бы объявили содержимое char * и передали адрес этого указателя на функцию. Эта функция затем выделит память, и ваш указатель будет указывать на содержимое при возврате.

0
ответ дан 1 December 2019 в 17:51
поделиться

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

Изменить

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

В C ++ я не могу понять указатели и классы

Каковы препятствия на пути к пониманию указателей и что может быть сделано, чтобы их преодолеть?

16
ответ дан 1 December 2019 в 17:51
поделиться

Указатели также отлично подходят для передачи изменяемого аргумента функции, чтобы вызывающая сторона могла «увидеть изменение». Вы можете спросить, «а почему бы не использовать ссылку?». Мне нравится аргумент Google:

http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Reference_Arguments

2
ответ дан 1 December 2019 в 17:51
поделиться

Из Википедии :

Ссылки C ++ отличаются от указателей в несколько основных способов:

  • Невозможно напрямую ссылаться на объект ссылки после это определено; любое проявление его имя относится непосредственно к объекту, ссылки.
  • Как только ссылка создана, она не может быть позже сделана ссылкой другой объект; мы говорим, что этого не может быть желание пересесть. Это часто делается с указатели.
  • Ссылки не могут быть нулевыми, тогда как указатели могут; каждая ссылка относится к какому-то объекту, хотя он может или может недействителен.
  • Ссылки не могут быть неинициализированы. Потому что невозможно повторно инициализировать ссылку, они должны быть инициализируются, как только они создано. В частности, местные и глобальные переменные должны быть инициализированы где они определены, и ссылки которые являются членами данных класса экземпляры должны быть инициализированы в список инициализаторов класса constructor.

С указанными выше ограничениями указатели - это все, что у вас есть в виде облегченного контейнера для ссылки на объект, особенно если вы делаете что-то с полиморфным или динамическим. Примером может служить динамический массив указателей чисто абстрактных классов для представления окон.

Поскольку мне лень думать о примере полиморфизма, я возьму один из cplusplus.com :

// pointers to base class
#include <iostream>
using namespace std;

class CPolygon {
  protected:
    int width, height;
  public:
    void set_values (int a, int b)
      { width=a; height=b; }
  };

class CRectangle: public CPolygon {
  public:
    int area ()
      { return (width * height); }
  };

class CTriangle: public CPolygon {
  public:
    int area ()
      { return (width * height / 2); }
  };

int main () {
  CRectangle rect;
  CTriangle trgl;
  CPolygon * ppoly1 = &rect;
  CPolygon * ppoly2 = &trgl;
  ppoly1->set_values (4,5);
  ppoly2->set_values (4,5);
  cout << rect.area() << endl;
  cout << trgl.area() << endl;
  return 0;
}

В В приведенном выше коде указатель CPolygon * используется для ссылки на объект CRectangle и объект CTriangle .

-3
ответ дан 1 December 2019 в 17:51
поделиться

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

Указатели часто используются в ситуациях программирования. Например, когда вы ссылаетесь на массив по имени, например array [i] = 3; Компилятор производит причудливую математику, которая в итоге превращает этот код в

(адрес массива) + (sizeof (элементы массива) * i) = 3;

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

1
ответ дан 1 December 2019 в 17:51
поделиться

С архитектурной точки зрения указатели - это экономичный способ моделирования отношения 0 .. n:

struct A {
  vector<const B *> *pBees;
  A() : pBees(nullptr) {}
  void notice_bee(const B *pB) { 
    if (!pBees)
      pBees = new vector<const B *>;
    pBees.push_back(pB)
  }
  ~A() { 
    delete pBees; // no need to test, delete nullptr is safe
  }
  size_t bees_noticed() { return pBees ? pBees->size : 0 }
};

Если подавляющему большинству объектов A никогда не потребуется обращать внимание на какие-либо объекты B, нет причин, по которым каждый объект A должен иметь вектор нулевой длины. В Gnu C ++ 4.0.1 sizeof (vector) равно 12; sizeof (vector *) равен 4.

0
ответ дан 1 December 2019 в 17:51
поделиться

Помимо эффективности и гибкости. Суть указателей в C / C ++ заключается в том, как работает аппаратное обеспечение, вы не можете использовать драйвер устройства, диспетчер памяти или эффективный кеш, не используя где-нибудь указатели

Одной из основных целей проектирования первого компилятора C было создание «переносимого языка ассемблера» и возможность делать на языке более высокого уровня все, что можно делать с традиционным ассемблером / машинным кодом. Это означает возможность манипулировать адресами напрямую - в этом и заключается смысл указателей.

Однако следуя принципу KISS, не используйте указатели, если они действительно не упрощают работу.

0
ответ дан 1 December 2019 в 17:51
поделиться

Suppose you write a text editor. In this case, you don't know the size of the document in advance. You might be tempted to declare something like

  char Document[10000];

but then certainly some day someone you will want to use your editor on a much larger document. So this attempt is futile; and what you need is a way to ask for new memory at runtime (instead of compile time).

The C++ way of doing this is using the operator new, which returns a pointer to the freshly allocated memory:

  char* pDocument = new char[getSizeOfDocument()];

(Note that this example is oversimplified. In real life, you would certainly not do it like this but instead use something like std::string and std::vector, which internally do this allocation for you.)

-1
ответ дан 1 December 2019 в 17:51
поделиться

Мне кажется, вы еще не узнали о динамическом распределении памяти. В C ++ есть два способа выделить память: статически и динамически. Вы уже знакомы со статическим распределением (т. Е. Объявлением переменных). Это замечательно, если на момент написания программы вы точно знаете, сколько переменных (или, скорее, памяти) вам нужно.

Но что, если вы этого не сделаете? Например, предположим, что вы читаете книгу, содержащую набор чисел, которые вам нужно отслеживать. Зачем? Не знаю, но дело не в этом.

Ну, вы могли бы начать с массива:

int array[100];

Но что, если в файле более 100 чисел? В конце концов вам понадобится более гибкое решение:

int *array = new int[size];
// do stuff
delete [] array;

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

0
ответ дан 1 December 2019 в 17:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: