В чем разница между указателями и глобальными переменными в C?

Я читаю Книга C чтобы попытаться получить лучшую основу в C. Хотя я думаю, что я вообще получаю концепцию указателей, одна вещь торчит для меня в том, что кажется, что он обобщает все, на что он указывает, в глобальную переменную (например, возможность использовать указатели для возврата значений из void функции), что, естественно, несет с собой все опасности, я полагаю.

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

6 ответов


они совершенно разные звери. Чтобы лучше объяснить, позвольте мне определить и то, и другое.

указатели:

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

Глобальные Переменные:

в программе у вас есть переменные в каждой функции. Это могут быть параметры функции, и те, которые определены внутри. Кроме того, у вас есть то, что известно как глобальные переменные. Эти переменные хранят информацию, доступ к которой имеют все функции в файле. Это может быть полезно для передачи таких вещей, как глобальное состояние или конфигурацию. Например, у вас может быть один под названием debug что ваш код проверяет перед печатью некоторых сообщений или для хранения глобального объекта состояния, например счет в видеоигре.

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

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


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

они никоим образом не связаны друг с другом напрямую.

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


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

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

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

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

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

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


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

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

вы можете иметь локальные указатели или глобальные не указатели. Понятия полностью ортогональны.


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

кроме того, из функции вы можете вернуть указатель на переменную, область действия которой находится в этой функции. Но это плохая идея, так как переменная существовала в стеке функции, и теперь это ушло.


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

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

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

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

Клиффорд