Си двойной указатель: Указатели в C++ | Уроки С++

Содержание

C Урок 26. Указатели и адреса. Часть 1 |

&nbsp

&nbsp

&nbsp

На данном уроке мы рассмотрим интересную тему. Это указатели и адреса.

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

Вернее, мы, конечно же, данную тему не рассмотрим. Мы её только легонько коснёмся. Рассмотреть в рамках одного урока такую серьёзную тему не получится. По ней будет как минимум 4 урока. Мы лишь проведём сегодня первое знакомство. Но это будет самое главное. Так как понимание указателей и адресов начинается именно здесь.

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

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

Также, думаю, практически все в курсе, что у меня есть некоторое количество уроков по приобретающим всё большую популярность микроконтроллерам. Вот там как раз мы работаем напрямую с памятью физической и в отладке видим именно её. Но это не важно. Урок данный будет вполне актуален и для МК. Нам же абсолютно нет дела до того, какую память мы видим. А видим мы именно ту память, с которой мы работаем.

Организована память, предоставленная программе, примерно вот таким образом

 

 

У каждой ячейки памяти существует адрес.

Почему адреса следуют друг за другом не подряд, а пропускаются по 4 байта?

Можно конечно показать и подряд, но я показал именно с учётом того, что мы пишем приложение под 32-разрядную систему. Хотя у нас практически у большинства установлены операционные системы 64-разрядные, но приложения, написанные под 32-битные системы, там прекрасно работают. У нас даже компилятор mingw предназначен для 32-разрядных систем. Пока мы будем писать с расчётом именно на 32-разрядные системы, так как, во-первых, они легче для понимания, во-вторых, из соображений совместимости, так как 32-рязрядные системы пока ещё существуют и хочется, чтобы наша программа запускалась и прекрасно работала и на них. Также у нас получается то, что наш урок актуален и для 32-разрядных МК, например для тех же stm32.

Так вот к чему я это всё?

А к тому, что считаю, что удобнее работать также с 32-битными ячейками памяти и зачастую к ним идёт приравнивание.

Вообще в одной такой ячейке получается по 4 ячейки 8-битных. Например, если мы объявляем переменную типа char и присваиваем ей какое-то значение, то это значение займёт только такую ячейку.

Ну что ж. Представим, что мы объявили переменную типа int, которая скорей всего занимает в памяти 32 бита (но не факт, это иногда проверять надо), назвав её, например a. Затем присвоили ей какое-то значение. В данном случае нам операционная система выделит какую-то ячейку памяти, ну пусть, например вот эту

 

 

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

Мы конечно же зададимся вопросом. А зачем нам адрес переменной? Мы же знаем её имя и в процессе написания программы мы прекрасно можем обратиться к нашей переменной по имени. Скажу лишь, что есть такие ситуации, когда нам требуется именно адрес переменной, так как, например, если мы передали значение переменной в другую функцию в качестве параметра, то у нас в данной функции создастся копия этой переменной и мы будем работать с ней, поэтому, если мы вдруг решим изменить значение нашей переменной, то мы не сможем этого сделать, имя её в другой функции не видно, то есть переменная не попала в область видимости. Но если мы как-то передадим адрес, то мы сможем уже работать с реальной переменной. И это лишь одна ситуация, таких очень много.

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

Для этого мы можем заранее объявить переменную-указатель типа int. Указатель такого типа будет указывать на переменные именно такого типа.

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

 

 

Объявление указателя очень похоже на объявление обычной переменной, только тут появляется наша пресловутая звёздочка, которая почему-то всех путает. А почему именно, да потому что ставится она возле имени переменной, а после типа данных ставится пробел. Можно, конечно, поступить и наоборот, поставить эту звёздочку возле типа данных, потом поставить пробел и лишь потом имя. Всё работать будет точно так же и это было бы правильнее для понимания, так как звёздочка относится именно к типу данных. Именно тип данных вместе со звёздочкой и есть тип переменной-указателя. Но существует соглашение, согласно которому звёздочка ставится перед именем. Поэтому мы просто должны чётко понимать, что тип данных вместе со звёздочкой – это то, что мы объявили переменную-указатель, а её имя – это только имя указателя. Потом ещё будет причина непонимания смысла указателей, когда мы встретим звёздочку немного в другом случае. Но это чуть позже.

Как это всё будет выглядеть практически?

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

 

unsigned int a;

a = 0xFE340056;

 

А теперь мы объявим переменную-указатель такого же типа

 

unsigned int *p_a;

 

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

Вообщем, в памяти у нас пока примерно вот такая картина

 

 

То есть, у нас есть переменная типа указателя на unsigned int, которая пока не хранит практически ничего, а переменная

a имеет уже значение, хранящееся по определённому адресу.

Как же присвоить адрес нашей переменной a нашему указателю p_a?

А делается это вот таким вот образом.

Существует специальная операция, называемая операцией взятия адреса.

Оператор данной операции выглядит в виде амперсанда

 

 

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

 

 

Здесь тоже присутствует некая путаница. Кто-то путает данный оператор с точно таким же оператором

побитового И, ровно как звёздочку изредка расценивают как операцию умножения.

Давайте теперь присвоим адрес нашей переменной a переменной-указателю p_a

 

p_a = &a;

 

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

Вот теперь переменная p_a хранит в себе адрес переменной a

 

 

Получается, что p_a знает теперь адрес a. То есть если, как в жизни, у нас есть такой человек, который знает адрес другого человека.

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

Ну конечно же любой ответит: Да как! Спросить у него надо!

Ну это в жизни. А здесь как? Да вообще элементарно. У нас p_a его и хранит, он является его значением. Просто присваиваем значение этого p_a любым переменным.

 

 

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

Ответ: мы это также можем сделать. Для этого мы должны произвести операцию разыменования указателя p_a.

Для разыменования у нас существует вот такой оператор

 

 

Да автор просто над нами прикалывается! – скажете вы.

Нет, не прикалывается. Опять эта звёздочка!

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

 

 

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

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

Поэтому, чтобы получить значение нашей переменной a, используя её указатель, мы можем сделать, например вот так

 

unsigned int b = *p_a;

 

Теперь переменная b получит значение переменной a, которое мы взяли у указателя на эту переменную, применив операцию разыменования.

С помощью разыменования мы можем также и изменить значение переменной a, используя указатель p_a, который хранит её адрес

 

*p_a = 0xE2222222;

 

Может также возникнет вопрос. Если указатель – это также переменная, которая тоже имеет в памяти свой адрес. Она же находится в памяти и занимает ячейку. А можем ли мы создать и на неё указатель?

Ну конечно же можем!

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

 

unsigned int **p_p_a;

 

Наш новый указатель теперь тоже получит своё место в памяти

 

 

Только этот указатель пока ни на что не показывает, то есть он пока не хранит никаких адресов.

И теперь мы вот таким образом присваиваем адрес указателя p_a, который указывает на переменную a, нашему новому указателю

 

p_p_a = &p_a;

 

Получится теперь у нас вот такая картина в памяти

 

 

То есть теперь p_p_a хранит адрес p_a, который в свою очередь хранит адрес a.

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

Ну и тогда резонный вопрос: а можем ли мы у этого человека узнать возраст третьего человека, ведь он знает адрес другого человека, который знает адрес третьего человека и который может спросить у третьего человека его возраст и сказать первому человеку?

Ну конечно можем. И причём в нашем случае программирования на языке C всё гораздо проще.

Мы также используем две звёздочки в операции разыменования

 

unsigned int b = **p_p_a;

 

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

Вот так. Теперь, надеюсь, к вам немного пришло понимание физики адресов. У адресов существует также ещё и арифметика, но об этом в другом уроке.

Теперь давайте немного поговорим о массивах.

Например существует у нас массив данных типа unsigned char, мы его объявили и сразу проинициализировали

 

unsigned char uch[10] = {0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC};

 

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

 

 

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

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

А, в принципе, его получать-то особо не всегда надо, так как имя массива и есть указатель на массив. Вот такая интересная получается история.

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

 

unsigned char *p_uch = &uch[0];

 

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

Теперь переменная p_uch хранит в себе адрес

Указатели в C++

Введение

В современном С+plus; использования указателей можно избежать во многих случаях.

Простейший пример

#include <iostream> using namespace std; /* Pointers */ int main() { int a = 5; int *px = &a; int *px2 = &a; //px is now an address in memory where variable a was stored cout << endl << "a = " << a; cout << endl << "pointer px: " << *px; // will show the value stored at this address cout << endl << "pointer px address: " << px; // will show the address in hex format cout << endl << "pointer px2 address: " << px2; a = 9; cout << endl << "a = " << a; cout << endl << "pointer px: " << *px; // will show the value stored at this address cout << endl << "pointer px address: " << px; // will show the address in hex format cout << endl << "pointer px2 address: " << px2; *px2 = 11; cout << endl << "a = " << a; cout << endl << "pointer px: " << *px; // will show the value stored at this address cout << endl << "pointer px address: " << px; // will show the address in hex format cout << endl << "pointer px2 address: " << px2; }

PS C:\Users\Andrei\cpp\SimpleCode\46> g++ .\46.cpp

PS C:\Users\Andrei\cpp\SimpleCode\46> .\a.exe a = 5 pointer px: 5 pointer px address: 0x7bfe0c pointer px2 address: 0x7bfe0c a = 9 pointer px: 9 pointer px address: 0x7bfe0c pointer px2 address: 0x7bfe0c a = 11 pointer px: 11 pointer px address: 0x7bfe0c pointer px2 address: 0x7bfe0c

#include <iostream> using namespace std; /* Pointers */ int main() { const int SIZE = 5; int arr[SIZE]{4,55,79,1,7}; for (int i = 0; i < SIZE; i++) { cout << arr[i] << endl; } // array name is a pointer to its first element int *pArr = arr; cout << "arr\t"<< arr << endl; cout << "pArr\t"<< pArr << endl; cout << "=============================" << endl; for (int i = 0; i < SIZE; i++) { cout << pArr[i] << endl; } cout << "=============================" << endl; // array is a continuous memory allocation // elements are going one by one without gaps in memory // that is why when we move pointer to the next value // we reach to the following array element for (int i = 0; i < SIZE; i++) { // by adding 1 here we are moving 4 bytes in the memory // because we have integer values cout << *(pArr + i) << endl; } cout << "=============================" << endl; for (int i = 0; i < SIZE; i++) { // using pointer to go through array cout << *(arr + i) << endl; } cout << "=============================" << endl; for (int i = 0; i < SIZE; i++) { // here we will get the memory addresses // note that the step is 4 bytes cout << (arr + i) << endl; } }

PS C:\Users\Andrei\cpp\SimpleCode\47> g++ .\47.cpp

4 55 79 1 7 arr 0x7bfde0 pArr 0x7bfde0 ============================= 4 55 79 1 7 ============================= 4 55 79 1 7 ============================= 4 1 7 ============================= 0x7bfde0 0x7bfde4 0x7bfde8 0x7bfdec 0x7bfdf0

что такое указатель Работа с указателями в языке си

  • Windows
  • Аудио/Видео
  • Безопасность 
  • Браузеры
  • Вопросы
  • Выбор

Поиск

  • Интересно
  • Интернет
  • Использование
  • Как исправить
  • Комп. грамотность

Операции над указателями. Типы указателей — Мегаобучалка

Над адресами в C++ определены следующие арифметические операции:

·сложение и вычитание указателей с константой;

·вычитание одного указателя из другого;

·инкремент;

·декремент.

Сложение и вычитание указателей с константой n означает, что указатель перемещается по ячейкам памяти на столько байт, сколько занимает nпеременных того типа, на который он указывает. Допустим, что указатель имеет символьный тип и его значение равно 100. Результат сложения этого указателя с единицей — 101, так как для хранения переменной типа char требуется 1 байт. Если же значение указателя равно 100, но он имеет целочисленный тип, то результат его сложения с единицей будет составлять 104, так как для переменной типа int отводится 4 байта.

Разность двух указателей – это разность их значений, деленная на размер типа в байтах. Так, разность указателей на третий и нулевой элементы массива равна трем, а на третий и девятый — шести. Суммирование двух указателей не допускается.

Инкремент перемещает указатель к следующему элементу массива, а декремент к предыдущему:

К указателям так же применимы операции отношения ==, !=, <,>,<=,>=. Иными словами, указатели можно сравнивать. Например, если i указывает на пятый элемент массива, а j — на первый, то отношение i>j истинно. Кроме того, любой указатель можно сравнивать на равенство с нулем. Однако, все эти утверждения верны, если речь идет об указателях, ссылающихся на один массив. В противном случае результат арифметических операций и операций отношения будет не определен.

 

Указатели на указатели.

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

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



Многочисленное перенаправление может и дальше расширяться. Но существует немного случаев, когда необходимо что-то более мощное, чем указатель на указатель. Излишнее перенаправленние приводит к концептуальным ошибкам, которые очень трудно исправлять. (Не надо путать многочисленное перенаправление со связанными списками, которые используются в базах данных.)

Переменная, являющаяся указателем на указателе должна быть описана следующим образом. Это выполняется путем помещения двух звездочек перед именем. Например, следующее объявление сообщается компилятору, что newbalance — это указатель на указатель типа float:

float **newbalance;

Важно понимать, что newbalance — это не указатель на число с плавающей точкой, а указатель на указатель на вещественное число.

Для получения доступа к целевому значению, косвенно указываемому указателем на указатель, следует применить оператор * два раза, как показано в следующем примере:

#include <stdio.h>
int main(void)
{
int x, *p, **q;
x = 10;
p = &x;
q = &p;
printf («%d», **q) ; /* вывод значения x */
return 0;
}

Здесь p объявляется как указатель на целое, a q — это указатель на указатель на целое. Вызов printf() выводит число 10 на экран.

 

 

Указатели и строки.

Строка– это последовательность (массив) символов (типа char), которая заканчивается специальным символом – признаком конца строки. Это символ записывается как ‘\0′ (не путайте с символом переноса строки’\n’) и равен 0. При вводе строки символ конца строки добавляется автоматически. Все функции работы со строками – и стандартные, и создаваемые программистом – должны ориентироваться на этот символ. Если требуется сформировать новую строку, то обязательно надо добавлять признак конца строки. Если этого не сделать, то при дальнейшей работе возникнут ошибки.

‘a’ // Символьная константа — один символ
«a» // Строковый литерал — массив из двух символов ‘a’ и ‘\0’, заменяется на адрес.
char str[51]; // Объявление строки
char *str; // Нельзя, т.к. не выделяется память под элементы строки
char *str = «abcd»; // Можно, но очень осторожно!
char *str1 = «abc», *str2 = «abc»; // Не известно, будет ли выполняться str1 == str2?

Строковым литералом называется последовательность символов, заключённых в двойные кавычки. В строковом литерале на один символ больше, чем используется при его записи – добавляется символ ‘\0’.

Тип строкового литерала есть «массив с надлежащим количество константных символов». Строковый литерал можно присвоить переменной типа char *. Это разрешается, потому что в предыдущих определениях С иC++ типом строкового литерала был char *. Однако изменение строкового литерала через такой указатель является ошибкой.

char *str = «С & С++»;  
str[2] = ‘?’; // Ошибка времени выполнения!

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

char str[] = «С & С++»; // Массив из 8 символов
str[2] = ‘?’; // Правильно

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

const char *error_massage()  
{ return «Недостаточно параметров»; } // После выхода из функции память, содержащая строку, не будет освобождена

 

Ссылочный тип данных.

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

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

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

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

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

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

·Значения ссылочного типа могут ссылаться только на значения того типа, который был указан при описании ссылочного типа.

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

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

Все описания ссылочных типов Ады можно условно разделить на три вида:

·ссылочные типы для динамической памяти

·обобщенные ссылочные типы

·ссылочные типы для подпрограмм

 

указатель в программировании на ассемблере, сегментная адресация

Указатель в программировании.

Указатель в программировании.

В статье MS-DOS и TASM 2.0. Часть 9. Указатель просто и понятно было рассмотрено, что такое указатель в программировании (pointer). Сейчас мы перейдём к вопросу практического использования указателя. Ещё раз напомним, что указатель в ассемблере — более широкое понятие, чем в Си и С++, где указатель определён как переменная, значением которой является адрес ячейки памяти. Указатель — не только переменная. Указатель в программировании на ассемблере — адрес определённой ячейки памяти. Жёсткой привязки к понятию «переменной» нет.

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

Указатель в программировании используется также для получения и передачи входных-выходных значений функций. С этим применением мы встретимся при Windows программировании.

Указатель — адрес ячейки памяти.

Указатель в программировании на ассемблере — адрес ячейки памяти, содержащей определённые последовательности цифр — блоки кода и данных. Блоки кода и данных называются значениями указателя, например: строка, массив, структура, функция, переменная, константа.

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

Указателю можно присвоить условное обозначение (const_a, const_b, my_mass_1, MY_STRUCT_1, BitMask, my_prnt_func), определив тип данных или кода, на которые он указывает (db, dd, STRUC, RECORD, proc). Практически мы уже проделывали эти операции, создавая исходники наших простейших программ:

… const_a db 5h const_b dd 15h … my_mass_1 db 10 dup(8) … MY_STRUCT_1 STRUC;В отличие от MASM — STRUC, а не STRUCT member_1 dw ?; member_2 db ?; MY_STRUCT_1 ENDS … BitMask RECORD f0:4=1,f1:4=1,f2:4=0,f3:4=0 … my_prnt_func proc PASCAL pMessage1:WORD, pMessage2:WORD local tmp:WORD mov ax,pMessage2 mov tmp,ax mov ah,09h mov dx,pMessage1 int 21h mov ah,09h mov dx,tmp int 21h ret my_prnt_func endp …

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

Передача массива как двойной указатель в c предупреждение

Давайте начнем с:

A

В m, arrмассив. В частности, это массив из 3 элементов, каждый из которых представляет собой массив из 4 элементов, каждый из которых является A. Таким образом, arrэто массив из 3 массивов из 4 int. Вы, наверное, слышали или читали, что массивы «декай»? для померов. Это разговорный термин. Фактическое правило, которое вы можете найти в пункте 6.3.2.1, параграфе 3, стандарта C 2011:

За исключением случаев, когда это операнд mоператора, mоператора, или одинарным *(A+m)оператора, или является строка символов используется для инициализации массива, выражение , которое имеет тип А € ?array из типа a € ?? преобразуется в выражение с типом ?poA + mer для ввода типа ? что poms к исходному элементу массива ob * (A + m) + nect и не является lvalue.

Вот как это правило применяется arrв n:

  • arrявляется идентификатором , то есть это имя какого-либо объекта. Таким образом, он обозначает свой объект. Этот объект представляет собой массив из 3 массивов из 4 int.
  • Этот массив не является операндом intили nили m, и это не строковый литерал. Итак, следуя правилу, он преобразуется из массива из 3 массивов из 4 intв указатель на первый массив из 4 int.

Что будет дальше? Ничего. Выражение, которое мы имеем, является указателем на массив из 4 int. Не существует правила, согласно которому указатель на массив преобразуется в указатель на указатель. У нас есть указатель на массив, но этот массив еще не используется в выражении, а не в простом выражении arr. Поэтому он не конвертируется.

Это означает, что вы передаете *(*(A+m)+n)указатель на массив из 4 int. Но в вашем заявлении printговорится, что он принимает указатель на указатель на int. Это разные вещи, и они несовместимы, поэтому компилятор предупреждает вас.

(Чтобы увидеть, что они несовместимы, рассмотрим разницу с указателем на массив из 4 intи указатель на указатель на int. Память указателя на массив из 4 intсодержит 4 intзначения. Память указателя на указатель на intсодержит указатель. Это разные вещи.)

Затем рассмотрим:

int

Мы знаем , что сверху , что вы должны изменить , *(A+m)+nчтобы print, который является указателем на массив 4 int. Вы также можете изменить его print(int A[][4], int m, int n), потому что в C есть правило, что такое объявление параметра будет автоматически скорректировано для printfудобства. Однако предположим, что вы храните его как A[m][n]. Тогда это *(*(A+m)+n)значит?

Так Aкак это указатель на указатель на a int, то это Aозначает добавить intк указателю. (Это странно разнос, кстати. mИ 4более тесно связаны с более высоким старшинства умножения , чем Aи mявляются добавлением, так почему они имеют рыхлую интервал? mБы изобразить смысл лучше.) Тогда *(A+m)значит добавить nк этому. В общем, мы переместили A+mэлементы за пределы Aточек. Так как Aточки указателя, мы указали указатель *(A+m)указателями. Тогда mразыгрывания. Когда вы разыскиваете указатель на указатель на a int, вы получаете указатель на int. Таким образом, результат этого выражения является указателем. Но ты хотел int.

Ссылка, на которую вы ссылаетесь, говорит о «2D-массиве». Типы массивов, о которых он говорит, реализуются с помощью указателей на указатели. Чтобы создать такой массив, вы создаете массив указателей, а затем каждый из этих указателей указываете на элементы строки. Затем указатель на этот массив указателей действует как 2D-массив, в том числе *(A+m)+nэлемент jстроки i. Если у вас массив вроде этого, вы можете обратиться к элементу nв строке , mиспользуя n. Эквивалентно, вы могли бы сослаться на это int. Что означает это выражение:

  • Возьмите указатель Aи добавьте mего. Поскольку Aуказывает на указатель на a int, добавление увеличивает mзначение указателя, чтобы указывать на mуказатели дальше. Вот где мы должны найти указатель на элементы строки m.
  • nполучает значение указателя, на которое mуказывает. Это значение должно быть указателем на элементы строки m, в частности указателем на первый элемент (с индексом 0).
  • *(*(A+m)+n)продвигает значение указателя, чтобы указать n intдальше. Вот где мы должны найти элемент nстроки m.
  • intполучает значение, на intкоторое *(A+m)+nуказывает.

Теперь предположим , что вместо того, чтобы вы изменили printбыть A[m][n]. Тогда ваше &A[0][0]заявление должно использовать print, как и раньше. Или он мог бы использовать int *A, также как и раньше. Но в этом случае выражение оценивается:

  • Aявляется указателем на массив из 4 int. Добавление mк нему увеличивает значение указателя на точечные mмассивы.
  • *((A+(m * 4) + n)))получает объект, на который intуказывает. Этот объект представляет собой целый массив. Таким образом, это выражение, которое обозначает массив. Следуя правилу C о массивах в выражениях, этот массив преобразуется в указатель на его первый элемент. Таким образом, intстановится указателем на первый элемент массива, пронумерованный m.
  • nпродвигает значение указателя, чтобы указать n intдальше. Вот где мы должны найти элемент nстроки m.
  • mполучает значение, на intкоторое Aуказывает.

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

Наконец, предположим , что вы передаете intв printи изменить свой параметр в A+(m * 4) + n. Теперь что такое выражение n? В этом случае вы обрабатываете массив из 3 массивов из 4 intкак один большой массив из 12 int. Затем вы вычисляете, где находится элемент nстроки m. В этом случае Aэто указатель на int(не указатель на указатель на int). То mесть вычисление, в котором должен находиться элемент nстроки m, и *((A+(m * 4) + n)))получает значение этого элемента.

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

Указатель на указатель или пример программы двойного указателя на C ++

Logo
  • Дом
  • С
  • C ++
  • Java
  • Котлин

Приложения

Facebook

Почта

Концепции программирования на C ++

Идти LITTLE DROPS

Переключить навигацию

  • Домашняя страница
  • Учебники по C ++
    • Основы в C ++
    • Элементы управления в C ++
    • Функции в C ++
    • Массив в C ++
    • Другие концепции в C ++
    • C ++
    • C ++ Блог
      • Классы в C ++
      • Наследование в C ++
      • Другие концепции OOPS
    • ПРОГРАММЫ C ++
      • Базовые примеры программ C ++
      • Примеры программ операторов C ++
      • Примеры программ C ++ Класса C ++
      • Общие примеры программ C ++
      • Примеры программ
      • Примеры программ конструктора C ++
      • Примеры программ перегрузки оператора C ++
      • Примеры программ массива C ++
      • Примеры программ указателей C ++
      • Примеры программ шаблонов C ++
    • ПРОГРАММЫ OOPS
      • Обработка исключений
      • Программы на C ++
      • 9 0004 Шаблоны в C ++
      • Виртуальный класс и функции в C ++
      • Структура и объединение в C ++
      • Операции с файлами в C ++
    • СТРУКТУРЫ ДАННЫХ
      • Программы стека
      • Программы очереди
      • Программы
      • Поиск программ
      • Связанный список

    Базовые примеры программ C ++

    Базовые примеры программ C ++

    1. Пример программы Hello World на C ++
    2. Простая программа для чтения пользовательского ввода с использованием cin
    3. Пример программы простого сложения (добавления двух целых чисел)
    4. Пример программы if на C ++
    5. если..else Пример программы на языке C ++
    6. Пример программы на лестничной диаграмме If Else
    7. Пример программы простого оператора Switch на C ++
    8. Пример программы цикла For на C ++
    9. Пример программы цикла while на C ++
    10. Пример программы цикла на C ++

    Примеры программ операторов C ++

    Примеры программ операторов C ++

    1. Пример программы простых арифметических операторов на C ++
    2. Пример программы простых операторов отношения на C ++
    3. Пример программы простых логических операторов на C ++
    4. Пример программы простых операторов присваивания на C ++
    5. Пример программы простых унарных операторов на C ++
    6. Пример программы простых условных или тернарных операторов на C ++
    7. Пример программы простых операторов с запятой на C ++
    8. Пример программы простого оператора разрешения области действия на C ++
    9. Пример программы простого нового оператора распределения памяти на C ++
    10. Простое удаление Пример программы оператора освобождения памяти на C ++

    Общие примеры программ на C ++

    Общие примеры программ на C ++

    1. Факториал с использованием примера программы цикла на C ++
    2. Факториал с использованием примера программы функции на C ++
    3. Факториал с использованием примера программы с рекурсией в C ++
    4. Программа-пример поиска простого числа (Method1) на C ++
    5. Программа-пример поиска простого числа (Method2) на C ++
    6. Серия примеров Фибоначчи на C ++
    7. Пример программы для умножения значения с использованием цикла For в C ++
    8. Пример программы для области круга C ++

    Miten Korjata S-указатель-двойной.из-онгельмат? [RATKAISTU]

    Pyyntö
    + втор-указатель double.out 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: SuSE Linux Office Desktop 2002
    Ohjelmistokehittäjä: SuSE Inc.
    Käyttöjärjestelmäversio: Linux
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Slackware Linux 10.1 Iss 66 мая 2005
    Ohjelmistokehittäjä: Формат Linux
    Käyttöjärjestelmäversio : Linux
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Slackware Linux 10.1 Iss 66 мая 2005
    Ohjelmistokehittäjä: Future Publishing
    Käyttöjärjestelmäversio : Linux
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Linux Format Выпуск 46 ноября 2003
    Ohjelmistokehittäjä: Future Publishing
    Käyttöjärjestelmäversio: Linux
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Solaris 10 марта 2005
    Ohjelmistokehittäjä: Sun Microsystems
    Käyttöjärjestelmäversio: Sparc
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Solaris 10 марта 2005
    Ohjelmistokehittäjä: Sun Microsystems
    Käyttöjärjestelmäversio: Solaris
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Solaris 10 Operating System 2005
    Ohjelmistokehittäjä: Sun Microsystems
    Käyttöjärjestelmäversio: Sparc
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель sиз 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Solaris 10 Operating System 2005
    Ohjelmistokehittäjä: Sun Microsystems
    Käyttöjärjestelmäversio: Windows NT
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    Tiedostohakemiston Sijainti: C: \ Windows \ System32 \
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Solaris 10 Operating System 2005
    Ohjelmistokehittäjä: Sun Microsystems
    Käyttöjärjestelmäversio: Solaris
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Solaris 10 Operating System 2005
    Ohjelmistokehittäjä: Sun Microsystems
    Käyttöjärjestelmäversio: WIndows 2000 Professional
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    Tiedostohakemiston Sijainti: C: \ Windows \ System32 \
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Solaris 10 Operating System 2005
    Ohjelmistokehittäjä: Sun Microsystems
    Käyttöjärjestelmäversio: Окна 98
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    Tiedostohakemiston Sijainti: C: \ Windows \ System32 \
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Solaris 10 Operating System 2005
    Ohjelmistokehittäjä: Sun Microsystems
    Käyttöjärjestelmäversio: Windows XP
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    Tiedostohakemiston Sijainti: C: \ Windows \ System32 \
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Red Hat Linux 9 2003
    Ohjelmistokehittäjä: Red Hat Software Inc.
    Käyttöjärjestelmäversio: Red Hat Linux 9
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Linux Format Issue 57 сентября 2004
    Ohjelmistokehittäjä: Future Publishing
    Käyttöjärjestelmäversio: Linux
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Linux Magazine Issue 46 сентября 2004
    Ohjelmistokehittäjä: Linux Magazine
    Käyttöjärjestelmäversio: Dyne: bolic 1.3
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Linux Magazine Issue 46 сентября 2004
    Ohjelmistokehittäjä: Linux Magazine
    Käyttöjärjestelmäversio: Gentoo 2004.1
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Linux Magazine Issue 46 сентября 2004
    Ohjelmistokehittäjä: Linux Magazine
    Käyttöjärjestelmäversio: Arch Linux 0.6
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Linux Magazine Issue 46 сентября 2004
    Ohjelmistokehittäjä: Linux Magazine
    Käyttöjärjestelmäversio: Slackware 10.0
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Linux Magazine Issue 46 сентября 2004
    Ohjelmistokehittäjä: Linux Magazine
    Käyttöjärjestelmäversio: Knoppix 3.4
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Suse Linux 9.0 Персональные 2003
    Ohjelmistokehittäjä: SuSE Inc.
    Käyttöjärjestelmäversio: SuSE LINUX 9.0
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Red Hat Enterprise Linux 4
    Ohjelmistokehittäjä: Red Hat Software Inc.
    Käyttöjärjestelmäversio: Red Hat Linux
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: Red Hat Enterprise Linux 4
    Ohjelmistokehittäjä: Red Hat Software Inc.
    Käyttöjärjestelmäversio: Linux
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107.00 Б
    BSD Magazine
    Ohjelmisto: BSD Magazine 2/2008 [2]
    Ohjelmistokehittäjä:
    Käyttöjärjestelmäversio: OpenBSD
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4
    + двойной указатель s.из 4546a55ddddbc776f7d1f4a331ea2632 107,00 B Pyyntö
    Ohjelmisto: SUSE Linux Enterprise Server 10 DVD 1 2006
    Ohjelmistokehittäjä: Novell Inc.
    Käyttöjärjestelmäversio: SuSE Linux 10.0
    Arkkitehtuuri: 64-bittinen (64)
    Tiedostokoko: 107
    MD5-tarkistussumma: 4546a55ddddbc776f7d1f4a331ea2632
    SHA1-tarkistussumma: 99e8f36ae33195eef5c09518e8fdecfc142db10f
    CRC32: 2446e0b4

    Указатели C ++


    Создание указателей

    Вы узнали из предыдущей главы, что мы можем получить память адрес переменной с использованием и оператор:

    Пример

    строка food = «Пицца»; // Переменная food типа string

    cout << еда; // Выводит значение еды (Пицца)
    cout << & food; // Выводит адрес памяти еды ( 0x6dfed4 )

    Пример запуска »

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

    Переменная-указатель указывает на тип данных (например, int или строка ) того же type и создается с помощью оператора * . Адрес переменной, с которой вы работаете, назначается указателю:

    Пример

    строка food = «Пицца»; // Переменная еды типа строка
    строка * ptr = и еда; // Переменная-указатель с именем ptr, в котором хранится адрес еды

    // Вывести стоимость еды (Пицца)
    cout << food << "\ n";

    // Вывод адрес памяти еды (0x6dfed4)
    cout << & food << "\ n";

    // Вывести адрес памяти еды с указателем (0x6dfed4)
    cout << ptr << "\ n";

    Пример запуска »
    Объяснение примера

    Создайте переменную-указатель с именем ptr , которая указывает на строковую переменную , используя знак звездочки * ( строка * ptr ).Обратите внимание, что тип указателя должен соответствовать типу переменной, которую вы работаю с.

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

    Теперь, ptr содержит значение адреса памяти food .

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

    строка * mystring; // Предпочтительный
    string * mystring;
    строка * mystring;



    определение указателя по The Free Dictionary

    Указатель Уиллоби, чем он мог описать ей оттенки своего разума.Известно, что английский пойнтер сильно изменился в течение последнего столетия, и в этом случае, как полагают, в основном это изменение было вызвано скрещиванием с гончей; но нас беспокоит то, что это изменение произошло бессознательно и постепенно, но в то же время настолько эффективно, что, хотя старый испанский пойнт определенно пришел из Испании, мистер Однако она часто говорила себе, что не должна раздражаться, обучая своего племянника почти каждый раз, когда она с указкой в ​​руке садилась, чтобы показать ему французский алфавит, ей так хотелось быстро и легко передать свои знания ребенку, который уже боялся, что тетя может в любой момент рассердиться, что на от малейшего его невнимания она дрожала, волновалась и разгоралась, повышала голос, а иногда тянула его за руку и ставила в угол.На его носу были циферблат и указатель. Он установил указатель на определенную станцию ​​в Большом Гелии, приподнял арочную крышку вещи, вошел и лег на обитое дно, нисколько не смущенный разочарованием, вызванным тем, что он пришел на место старого князя Весловского. — весело поздоровался Левин, заявив, что был с ним знаком, и, схватив Гришу в карету, поднял его над указкой, которую привез с собой Степан Аркадьич. существовал в период его слабоумия, у старика не было ни одного друга, который оплакивал бы его, и действительно, за всю свою жизнь он ни разу не приложил ни малейших усилий, чтобы заполучить его.Вот как это. «Джоан Дербейфилд, когда она говорила, изогнула намокшие большой и указательный пальцы в форме буквы C, а другой указательный палец использовала как указатель». «В настоящий момент, — говорит он вам. Отец, «твое сердце окружено там кругом, и все вокруг там; это пространство все еще открыто », — говорит А. Теперь вы можете подумать, что первое, что сделает король после прослушивания такой новеллы от совершенно незнакомого человека, — это попросить верительные грамоты — да, и пару указателей в качестве до местности, где расположен замок, лучший путь к нему и т. д.Барометр был неисправен, и у него не было стрелки, кроме стационарного медного указателя, но я знал об этом только после того, как никакая погода не помешала ему в этих пастырских экскурсиях: дождь или ясная погода, он будет, когда часы его утренних занятий были возьмите его шляпу и, вслед за старым указателем своего отца, Карло, отправляйтесь на миссию любви или долга — я не знаю, в каком свете он ее рассматривал. Он строго следует традициям в одежде и манерах; но, совая нос в места, где ему не место, он мог указать на циветт или галку.Мои спортивные собаки состоят из двух пойнтеров, двух луни и двух сеттеров.

    двойной указатель — это … Что такое двойной указатель?

  • Двуносая андская тигровая гончая — Страна происхождения Боливия Признаки Классификация и стандарты Собака (Canis lupus knownis)… Wikipedia

  • Указатель-кликер — Указатель и щелчок Указатель и щелчок (англ. «Укажи и щелкни») представляют простое действие, которое можно использовать для графической информативной среды.L utilisateur déplace le pointeur d un dispositif de pointage…… Wikipédia en Français

  • Pointer et cliquer — (англ. «Укажи и щелкни») представляет простое действие, которое может быть использовано в графическом информативном окружении. L utilisateur déplace le pointeur d un dispositif de pointage (généralement, souris ou manette de…… Wikipédia en Français

  • Pointer-et-cliquer — (англ. «Укажи и щелкни») есть действия, которые используются для выполнения на графическом интерфейсе.L utilisateur déplace le pointeur d un dispositif de pointage (généralement, souris ou manette de jeu) на…… Wikipédia en Français

  • Лодка-пойнтер — Лодка-пойнтер была разработана Джоном Кокберном и построена Джоном, его сыном и внуком, с 1850-х по 1969 год. [Секссмит, Эйлин (1992). Историческое общество долины Оттавы. http://www.pembrokeontario.com/content/visiting here / sessions / the…… Wikipedia

  • Двойное сравнение и замена — (DCAS или CAS2) — это атомарный примитив, предложенный для поддержки определенных методов параллельного программирования.DCAS берет две необязательно смежные ячейки памяти и записывает в них новые значения только в том случае, если они соответствуют предварительно заданным ожидаемым значениям; как…… Википедия

  • Double Dribble (видеоигра) — Разработчик (и) Double Dribble Издатель (ы) Konami… Википедия

  • Double-Clic — Une souris d ordinateur possible trois boutons (bouton de gauche, bouton du milieu ou molette et bouton de droite) En informatique, le terme double clic est le nom donné à une action consistant à appuyer rapidement deux fois de suite sur un des…… Wikipédia en Français

  • Double clic — Une souris d ordinateur possible trois boutons (bouton de gauche, bouton du milieu ou molette et bouton de droite) En informatique, le terme double clic est le nom donné à une action consistant à appuyer rapidement deux fois de suite sur un des…… Wikipédia en Français

  • Double free — Double free () (doppelter Aufruf der Funktion free) bezeichnet einen Fehler в Computerprogrammen, wenn diese versuchen den gleichen Speicherbereich mehrmals freizugeben.Двойной свободный ist eine Potentielle Sicherheitslücke. Der Name leitet sich von…… Deutsch Wikipedia

  • Double free () — (doppelter Aufruf der Funktion free) bezeichnet einen Fehler в Computerprogrammen, wenn diese versuchen den gleichen Speicherbereich mehrmals freizugeben. Двойной свободный ist eine Potentielle Sicherheitslücke. Der Name leitet sich von der Funktion…… Deutsch Wikipedia

  • .

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Theme: Overlay by Kaira Extra Text
Cape Town, South Africa