Всегда ли C использует указатели для обработки адресов? - PullRequest
0 голосов
/ 13 февраля 2019

Насколько я понимаю, все случаи, когда C должен обрабатывать адрес, включают использование указателя.Например, операнд & создает указатель на программу, а не просто дает пустой адрес в качестве данных (т. Е. Он никогда не дает адрес без предварительного использования указателя):

scanf("%d", &foo)

Или при использовании &операнд

int i; //a variable
int *p; //a variable that store adress
p = &i; //The & operator returns a pointer to its operand, and equals p to that pointer.

Мой вопрос: есть ли причина, по которой программам на С всегда приходится использовать указатель для управления адресами?Есть ли случай, когда C может обрабатывать пустой адрес (числовое значение адреса) самостоятельно или с помощью другого метода?Или это совершенно невозможно?(Это связано с архитектурой системы, изменением распределения памяти во время и во время выполнения и т. Д.).И наконец, было бы полезно, если бы адреса менялись из-за управления памятью?Если бы это было так, это было бы причиной, по которой всегда нужны указатели.

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

Редактировать: Так как на часть вопроса был дан ответв комментариях Эрика Постпишила, Михаила Маршалека, user3386109, Майка Холта и Гекко;Я сгруппирую эти биты здесь: Да, использование пустых адресов не имеет смысла или бесполезно из-за различных факторов (указатели допускают несколько операций, адреса могут меняться при каждом запуске программы и т. Д.).Как отметил Михал Маршалек (без каламбура), scanf () использует указатель, потому что C может работать только с копиями, поэтому указатель необходим для изменения используемой переменной.то есть

int foo;
scanf("%d", foo) //Does nothing, since value can't be changed
scanf("%d", &foo) //Now foo can be changed, since we use it's address.

Наконец, как упоминал Гекко, существуют указатели для представления косвенности, так что компилятор может различать данные и адреса.

Джон Боде охватывает большинство этих тем вэто ответ, поэтому я отмечу это.

Ответы [ 3 ]

0 голосов
/ 13 февраля 2019

C позволяет конвертировать указатели в целые числа.Заголовок <stdint.h> предоставляет тип uintptr_t со свойством, что любой указатель на void может быть преобразован в uintptr_t и обратно, и результат будет сравниваться равным исходному указателю.

Per C2018 6.3.2.3 6, результат преобразования указателя в целое число определяется реализацией.Ненормативная записка 69 гласит: «Функции отображения для преобразования указателя в целое число или целое число в указатель предназначены для согласования со структурой адресации среды выполнения».

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

0 голосов
/ 13 февраля 2019

Указатель - это адрес (или, точнее, это абстракция адреса).Указатели - это то, как мы работаем со значениями адресов в C.

За исключением нескольких доменов, значение «голого адреса» само по себе просто бесполезно.Нас меньше интересует адрес, чем объект по этому адресу.C требует от нас, чтобы использовать указатели в двух ситуациях:

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

В этих случаях нам все равно, какое значение адреса на самом деле;нам просто нужно получить доступ к интересующему нас объекту.

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

0 голосов
/ 13 февраля 2019
int i; //a variable
int *p; //a variable that store adres
i = 10; //now i is set to 10
p = &i; //now p is set to i address
*p = 20; //we set to 20 the given address
int tab[10]; // a table
p = tab; //set address
p++; //operate on address and move it to next element tab[1]

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

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

В C у нас нет ссылок, поэтому мы должны использовать указатели.

void fun(int j){
j = 10;
}
void fun2(int *j){
*j = 10;
}
int i;
i = 5; // now I is set to 5
fun(i);
//printf i will print 5
fun2(&i);
//printf I will print 10
...