Как изменить адрес переменной c

Изменить адрес указателя C++ Решение и ответ на вопрос 1455246

Disabled7

1 / 1 / 0

Регистрация: 24.02.2015

Сообщений: 18

1

Изменить адрес указателя

23.05.2015, 10:50. Показов 5481. Ответов 12

Метки нет (Все метки)


Подскажите пожалуйста, как изменить не только адрес куда указывает указатель, но и адрес самого указателя
Для примера:

C++
1
2
3
4
5
char *a="one";
char *b="two";
 
a=b; // ок
&a=&b; // lvalue required as left operand of assignment

Я так понимаю lvalue это значение на которое можно получить ссылку, в чем тогда тут проблема? Объясните плиз

__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь



0



Programming

Эксперт

94731 / 64177 / 26122

Регистрация: 12.04.2006

Сообщений: 116,782

23.05.2015, 10:50

12

2549 / 1208 / 358

Регистрация: 30.11.2013

Сообщений: 3,826

23.05.2015, 10:53

2

почитайте об lvalue ? По простому, lvalue — это типы значений, которые могут стоять слева от знака равно. Как адресс (32-и битное значение(в вин32)) может стоять слева??? Число 15 тоже 32-ух битное значение. Вы же не пишите 5 = 11. Так почему тут пытаетесь?????



0



1 / 1 / 0

Регистрация: 24.02.2015

Сообщений: 18

23.05.2015, 11:00

 [ТС]

3

Дак а как изменить адрес указателя?



0



Черный мечник

55 / 56 / 34

Регистрация: 29.12.2012

Сообщений: 478

23.05.2015, 11:09

4

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
 
using namespace std;
 
 
int main()
{
setlocale(LC_ALL,"Rus");
int a=3,b=6;
int *c=&a;
cout<<"Адрес указателя с:"<<c<<endl;
c=&b;
cout<<"Адрес указателя с:"<<c<<endl;
    system("pause"); 
    return 0;
}



0



Эксперт PHP

4839 / 3852 / 1598

Регистрация: 24.04.2014

Сообщений: 11,300

23.05.2015, 11:10

5

Цитата
Сообщение от Disabled7
Посмотреть сообщение

Дак а как изменить адрес указателя?

никак



0



55 / 56 / 34

Регистрация: 29.12.2012

Сообщений: 478

23.05.2015, 11:10

6

Согласен с rikimaru2013, читать вам и читать



0



1 / 1 / 0

Регистрация: 24.02.2015

Сообщений: 18

23.05.2015, 11:14

 [ТС]

7

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



0



2549 / 1208 / 358

Регистрация: 30.11.2013

Сообщений: 3,826

23.05.2015, 11:16

8

Лучший ответ Сообщение было отмечено Disabled7 как решение

Решение

Объясню почему нельзя:
указатель — это переменная, которая хранит адресс. Переменная — это участок в памяти обладающий значением. Представьте себе улицу и куча домов. У дома есть адресс. Создали новый дом — дали ему адресс. И тут вы такой приходите, волосы назад, я хочу чтобы у этого красного дома был адресс не Березная 15, а Толчево 32. Как?!??! Если снести дом по старому адрессу и построить по новому, то это уже новый дом будет, хоть он и будет полной копией старого(конструктор копирование).

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



0



Jewbacabra

Эксперт PHP

4839 / 3852 / 1598

Регистрация: 24.04.2014

Сообщений: 11,300

23.05.2015, 11:18

9

Цитата
Сообщение от Jewbacabra
Посмотреть сообщение

никак

что-то я погарячился

C++
1
2
3
4
5
6
7
8
9
10
int a = 5;
    int b = 6;
    int* pa = &a;
    int* pb = &b;
    int** pp = new int*;
    *pp = pa
    cout << *pp << endl;
    *pp = pb;
    cout << *pp << endl;
    delete pp;



1



1 / 1 / 0

Регистрация: 24.02.2015

Сообщений: 18

23.05.2015, 11:18

 [ТС]

10

Понял, спасибо



0



rikimaru2013

2549 / 1208 / 358

Регистрация: 30.11.2013

Сообщений: 3,826

23.05.2015, 11:26

11

C++
1
2
3
4
5
6
7
8
9
10
int a = 5;
    int b = 6;
    int* pa = &a;
    int* pb = &b;
    int** pp = new int*;
    *pp = pa
    cout << *pp << endl;
    *pp = pb;
    cout << *pp << endl;
    delete pp;

1) указатель типа int** ссылается(имеет значение), то на однин указатель(0x00000002), то на другой (0x00000003), но сам указатель о котором спрашивает ТС то всеравно будет (0x00000007) на протяжение всей своей жизни(он в стеке, кто не понял)
2) код с UB

P.S. я не хотел комментировать данный код, но новичку показывать такой код нельзя — он не поймёт почему UB даже тут, и будет его юзать



0



Эксперт PHP

4839 / 3852 / 1598

Регистрация: 24.04.2014

Сообщений: 11,300

23.05.2015, 11:36

12

rikimaru2013, а в чем UB?



1



rikimaru2013

2549 / 1208 / 358

Регистрация: 30.11.2013

Сообщений: 3,826

23.05.2015, 11:46

13

Мои глаза хотели спать) Увидел

C++
1
delete *pp;



0



Операции с указателями

Последнее обновление: 23.09.2017

Указатели поддерживают ряд операций: присваивание, получение адреса указателя, получение значения по указателю,
некоторые арифметические операции и операции сравнения.

Присваивание

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

Присвоение указателю адреса уже рассматривалось в прошлой теме. Для получения адреса объекта используется операция &:

int a = 10;
int *pa = &a;	// указатель pa хранит адрес переменной a

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

Присвоение указателю другого указателя:

#include <iostream>
using std::cout;
using std::endl;

int main()
{
	int a = 10;
    int b = 2;
     
    int *pa = &a;
    int *pb = &b;
     
    cout << "Variable a: address=" << pa << "t value=" << *pa << endl;
    cout << "Variable b: address=" << pb << "t value=" << *pb << endl;
     
    pa = pb;    // теперь указатель pa хранит адрес переменной b
    cout << "Variable b: address=" << pa << "t value=" << *pa << endl;
    
	return 0;
}

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

Нулевые указатели

Нулевой указатель (null pointer) — это указатель, который не указывает ни на какой объект. Если мы не хотим, чтобы указатель указывал на какой-то конкретный адрес, то можно присвоить ему условное нулевое значение.
Для создания нулевого указателя можно применять различные способы:

int *p1 = nullptr;
int *p2 = NULL;
int *p3 = 0;

Ссылки на указатели

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

#include <iostream>

int main()
{
	int a = 10;
	int b = 6;
	
	int *p = 0;		// указатель
	int *&pRef = p;		// ссылка на указатель
	pRef = &a;			// через ссылку указателю p присваивается адрес переменной a
	std::cout << "p value=" << *p << std::endl;	// 10
	*pRef = 70;			// изменяем значение по адресу, на который указывает указатель
	std::cout << "a value=" << a << std::endl;	// 70
	
	pRef = &b;			// изменяем адрес, на который указывает указатель
	std::cout << "p value=" << *p << std::endl;	// 6
 	
	return 0;
}

Разыменование указателя

Операция разыменования указателя представляет выражение в виде *имя_указателя. Эта операция позволяет получить объект по адресу, который хранится в указателе.

#include <iostream>
using std::cout;
using std::endl;

int main()
{
	int a = 10;
     
    int *pa = &a;
    int *pb = pa;
     
    *pa = 25;
     
    cout << "Value on pointer pa: " << *pa << endl;  // 25
    cout << "Value on pointer pb: " << *pb << endl;  // 25
    cout << "Value of variable a: " << a << endl;    // 25
    
	return 0;
}

Через выражение *pa мы можем получить значение по адресу, который хранится в указателе pa, а через выражение типа
*pa = значение вложить по этому адресу новое значение.

И так как в данном случае указатель pa указывает на переменную a, то при изменении значения по адресу, на который указывает указатель, также изменится и значение
переменной a.

Адрес указателя

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

int a = 10;
int *pa = &a;
std::cout << "address of pointer=" << &pa << std::endl;        // адрес указателя
std::cout << "address stored in pointer=" << pa << std::endl;  // адрес, который хранится в указателе - адрес переменной a         
std::cout << "value on pointer=" << *pa << std::endl;          // значение по адресу в указателе - значение переменной a

Операции сравнения

К указателям могут применяться операции сравнения >, >=,
<, <=,==, !=. Операции сравнения применяются только к
указателям одного типа и к значениям NULL и nullptr. Для сравнения используются номера адресов:

#include <iostream>
using std::cout;
using std::endl;

int main()
{
	int a = 10;
	int b = 20;
	int *pa = &a;
	int *pb = &b;
	
	if(pa > pb)
		cout << "pa (" << pa << ") is greater than pb ("<< pb << ")" << endl;
	else
		cout << "pa (" << pa << ") is less or equal pb ("<< pb << ")" << endl;
    
	return 0;
}

Консольный вывод в моем случае:

pa (0x60fe94) is greater than pb (0x60fe90)

Приведение типов

Иногда требуется присвоить указателю одного типа значение указателя другого типа. В этом случае следует выполнить операцию приведения типов с помощью операции (тип_указателя *):

#include <iostream>

int main()
{
	char c = 'N';
	char *pc = &c;
	int *pd = (int *)pc;
	void *pv = (void*)pc;
	std::cout << "pv=" << pv << std::endl;
	std::cout << "pd=" << pd << std::endl;

	return 0;
}

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

Кроме того, следует отметить, что указатель на тип char (char *pc = &c) при выводе на консоль система интерпретирует как строку:

std::cout << "pc=" << pc << std::endl;

Поэтому если мы все-таки хотим вывести на консоль адрес, который хранится в указателе типа char, то это указатель надо преобразовать к другому типу, например, к void* или к int*.

Добавлено 1 июня 2019 в 03:51

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

Работа со значениями указателей

Модификация и разыменование указателей

Есть два значения, связанные с указателем. Первое – это адрес памяти, который хранится в самом указателе, а второе – это данные, которые хранятся по этому адресу памяти. Чтобы изменить адрес, сохраненный в переменной указателя, вы просто используете знак равенства.

RxByte_ptr = 0x40;

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

ReceivedData = *RxByte_ptr;
*TxByte_ptr = TransmitData;

Доступ к значению, на которое ссылается указатель, называется разыменованием, а звездочка (при использовании с указателями) называется оператором разыменования.

Рисунок 1 – Разыменование указателя

Рисунок 1 – Разыменование указателя

Получение адреса переменной

Важной деталью, связанной с использованием указателей, является оператор адреса в языке C; его символом является &. Хотя & присоединяется к обычным переменным, а не к указателям, я всё же считаю его «оператором указателя», потому что его использование очень тесно связано с реализацией указателя.

Если перед именем переменной стоит символ &, программа использует адрес переменной, а не ее значение.

Рисунок 2 – Получение адреса переменной

Рисунок 2 – Получение адреса переменной

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

char DisplayChar;
char TestingVariable;
char *DisplayChar_ptr;

DisplayChar = 0x41;
DisplayChar_ptr = &DisplayChar;
TestingVariable = *DisplayChar_ptr;
*DisplayChar_ptr = 0x42;
TestingVariable = DisplayChar;

Рассмотрим шаг за шагом, что именно делает этот код.

DisplayChar = 0x41;

Переменная DisplayChar сейчас хранит значение, соответствующее ASCII символу ‘A‘.

DisplayChar_ptr = &DisplayChar;

Указатель (DisplayChar_ptr) теперь содержит адрес переменной DisplayChar. Мы не знаем, что это за адрес, то есть мы не знаем число, которое хранится в DisplayChar_ptr. Кроме того, нам не нужно это знать; это дело компилятора, а не наше.

TestingVariable = *DisplayChar_ptr;

TestingVariable теперь содержит значение переменной DisplayChar, а именно 0x41.

*DisplayChar_ptr = 0x42;

Мы только что использовали указатель для изменения значения, хранящегося по адресу, соответствующему переменной DisplayChar; теперь она содержит значение 0x42, что является ASCII символом ‘B‘.

TestingVariable = DisplayChar;

TestingVariable теперь содержит значение 0x42.

Арифметика указателей

В основном, переменная в языке C содержит значение, которое может изменяться, и переменные-указатели не являются исключением. Обычными арифметическими операциями, которые используются для изменения значения указателя, являются сложение (например, TxByte_ptr = TxByte_ptr + 4), вычитание (TxByte_ptr = TxByte_ptr - 4), инкремент/увеличение (TxByte_ptr++) и декремент/уменьшение (TxByte_ptr--). Можно вычесть один указатель из другого, если два указателя имеют одинаковый тип данных. Однако вы не можете добавить один указатель к другому.

Арифметика указателей не так проста, как кажется. Допустим, у вас есть указатель с типом данных long. Вы отлаживаете некоторый код и в настоящее время выполняете пошаговую процедуру, которая многократно инкрементирует (увеличивает) этот указатель. Вы замечаете в своем окне отладки, что значение указателя с каждым шагом инкремента увеличивается не на единицу. Что тут происходит?

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

Рисунок 3 – Изменение значения указателя при инкременте

Рисунок 3 – Изменение значения указателя при инкременте

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

Указатели и массивы

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

Например, допустим, что у вас есть указатель с именем TxBuffer на char, который сейчас хранит адрес 0x30. В следующем фрагменте кода показаны два эквивалентных способа доступа по адресу 0x31.

TxByte = *(TxBuffer + 1);
TxByte = TxBuffer[1];

Когда использовать указатели

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

Указатель против массива

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

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

Передача указателя в функции

Широкое использование функций помогает вам писать организованный и модульный код. Это хорошо, хотя C накладывает ограничение, которое может быть в некоторых ситуациях неудобным: функция может иметь только одно возвращаемое значение. Другими словами, она может изменять только одну переменную – если только вы не используете указатели.

Эта техника работает следующим образом:

  1. добавьте указатель в качестве одного из входных параметров для функции;
  2. используйте оператор &, чтобы передать адрес переменной в функцию;
  3. внутри функции адрес переменной становится значением указателя, и функция использует оператор разыменования для изменения значения исходной переменной;
  4. даже если исходная переменная не изменяется напрямую с помощью возвращаемого значения, код, следующий за функцией, предполагает, что значение переменной было изменено.

Вот пример:

#define STEPSIZE 3

void IncreaseCnt_and_CheckLED(char *Count)
{
  *Count = *Count + STEPSIZE;
  if(LED == TRUE)
    return TRUE;
  else
    return FALSE;
}

int main()
{
  char RisingEdgeCount = 0;
  bit LED_State;

  ...
  ...
  LED_State = IncreaseCnt_and_CheckLED(&RisingEdgeCount);
  ...
  ...
} 

Заключение

Я надеюсь, что теперь у вас есть четкое представление о том, что такое указатели, и как начать работать с ними в вашем проекте прошивки на языке C. Если есть еще какие-либо аспекты встроенного ПО на C, которые вы хотели бы обсудить в будущих статьях, напишите об этом в комментариях ниже.

Теги

MCUВысокоуровневые языки программированияВычисления во встраиваемых системахМикроконтроллерРазработка ПО для встраиваемых системЯзык C

Переменные, адреса и указатели

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

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

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

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

int i = 0;
printf ("i=%d, &i=%p n", i, &i);

В результате выполнения данного программного кода на экране появляется примерно следующее (шестнадцатеричное число у вас будет другим):

i=0, &i=0x7fffa40c5fac 

Знак амперсанда (&) перед переменной позволяет получить ее адрес в памяти. Для вывода адреса переменной на экран используется специальный формат %p. Адреса обычных переменных (не указателей) в процессе выполнения программы никогда не меняются. В этом можно убедиться:

int a = 6;
float b = 10.11;
char c = 'k';
 
printf("%5d - %pn", a, &a);
printf("%5.2f - %pn", b, &b);
printf("%5c - %pn", c, &c);
 
a = 2; 
b = 50.99; 
c = 'z';
 
printf("%5d - %pn", a, &a);
printf("%5.2f - %pn", b, &b);
printf("%5c - %pn", c, &c);

Результат:

    6 - 0x7fff653532e0
10.11 - 0x7fff653532e4
    k - 0x7fff653532df
    2 - 0x7fff653532e0
50.99 - 0x7fff653532e4
    z - 0x7fff653532df

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

Зная адрес, можно получить значение, которое находится по этому адресу, поставив знак * перед адресом:

int a = 8;
printf("%d n", *&a);

На экране будет выведено число 8.

Однако запись типа &a не всегда возможна или удобна. Поэтому существует специальный тип данных — указатели, которым и присваивается адрес на область памяти.

Указатели в языке C, как и другие переменные, являются типизированными, т.е. при объявлении указателя надо указывать его тип. Как мы узнаем позже, с указателями можно выполнять некоторые арифметические операции, и именно точное определение их типа позволяет протекать им корректно. Чтобы объявить указатель, надо перед его именем поставить знак *. Например:

int *pi;
float *pf;

Обратите внимание на то, что в данном случае * говорит о том, что объявляется переменная-указатель. Когда * используется перед указателем не при его объявлении, а в выражениях, то обозначает совсем иное — «получить значение (данные) по адресу, который присвоен указателю». Посмотрите на код ниже:

int x = 1, y, z = 3;
int *p, *q;
 
p = &x;
printf("%dn", *p); // 1
 
y = *p;
printf("%dn", y); // 1
 
*p = 0;
printf("%d %dn", x, y); // 0 1
 
q = &z;
printf("%dn", *q); // 3
 
p = q;
*p = 4;
printf("%dn", z); // 4
 
printf("%p %pn", p, q); // p == q

С помощью комментариев указаны текущие значения ячеек памяти. Подробно опишем, что происходит:

  1. Выделяется память под пять переменных: три типа int и два указателя на int. В ячейки x и z записываются числа 1 и 3 соответственно.
  2. Указателю p присваивается адрес ячейки x. Извлекая оттуда значение (*p), получаем 1.
  3. В область памяти, которая названа именем у, помещают значение равное содержимому ячейки, на которую ссылается указатель p. В результате имеем две области памяти (x и y), в которые записаны единицы.
  4. В качестве значения по адресу p записываем 0. Поскольку p указывает на x, то значение xменяется. Переменная p не указывает на y, поэтому там остается прежнее значение.
  5. Указателю q присваивается адрес переменной z. Извлекая оттуда значение (*q), получаем 3.
  6. Переменной p присваивается значение, хранимое в q. Это значит, что p начинает ссылаться на тот же участок памяти, что и q. Поскольку q ссылается на z, то и p начинает ссылаться туда же.
  7. В качестве значения по адресу p записываем 4. Т.к. p является указателем на z, следовательно, меняется значение z.
  8. Проверяем, p и q являются указателями на одну и туже ячейку памяти.

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

int *pi;
float *pf;
 
printf("%lun", sizeof(pi)); 
printf("%lun", sizeof(pf));

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

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

int *pa, *pb;
float *pc;
 
printf(" %p %p %pn", pa, pc, pb);
 
// может возникнуть ошибка
printf(" %d %fn", *pa, *pc); 

Результат (в Ubuntu):

 0x400410 0x7fff5b729580 (nil)
 -1991643855 0.000000

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

int a = 5;
float c = 6.98;
int *pa;
float *pc;
 
pa = NULL;
pc = NULL;
 
printf(" %15p %15pn", pa, pc);
 
// Error
// printf(" %15d %15fn", *pa, *pc);
 
pa = &a;
pc = &c;
 
printf(" %15p %15pn", pa, pc);
printf(" %15d %15fn", *pa, *pc);

Результат (в Ubuntu):

           (nil)           (nil)
  0x7ffd8e77e550  0x7ffd8e77e554
               5        6.980000

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

На этом уроке вы должны понять, что такое адрес переменной и как его получить (&var), что такое переменная-указатель (type *p_var; p_var = &var) и как получить значение, хранимое в памяти, зная адрес ячейки (*p_var). Однако у вас может остаться неприятный осадок из-за непонимания, зачем все это надо? Это нормально. Понимание практической значимости указателей придет позже по мере знакомства с новым материалом.

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

Курс с решением части задач:
pdf-версия, android-приложение

Понравилась статья? Поделить с друзьями:

Читайте также:

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

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии