Указатель (тип данных)

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

Указатель (англ. pointer) — переменная, диапазон значений которой состоит из адресов ячеек памяти или специального значения — нулевого адреса. Последнее используется для указания того, что в данный момент указатель не ссылается ни на одну из допустимых ячеек. Указатели были изобретены Ющенко Екатериной Логвиновной в Адресном языке программирования (1955 г.), а не Harold Lawson в 1964 г., как долгое время считали за рубежом[1]. В 1955 г. в Адресном языке программирования были введены понятия косвенной адресации и адресации высших рангов, что покрывает понятие указателя и области его применения в современных языках программирования.

Область применения

Указатели применяются в двух сферах:

  • Работа в системе косвенной адресации (как в языках ассемблера). Одним из её преимуществ можно назвать экономию памяти. Делая указатель на файл, мы читаем его с диска, а не загружаем в ОЗУ. Передавая указатель на переменную в функцию мы не делаем копию этой переменной, а редактируем её напрямую[2]. Указатели используют для хранения адресов точек входа для подпрограмм в процедурном программировании и для подключения динамических подключаемых библиотек.
  • Динамическое управление памятью. В таком случае выделяется место в так называемой куче (динамической памяти), а переменные, для которых память выделена таким образом, называются динамическими[3]. В языке Си нет понятия строковой переменной, так что для строк часто используют указатель на массив символов.

Действия над указателями

Языки программирования, в которых предусмотрен тип указателей, содержат, как правило, две основные операции над ними: присваивание и разыменование.

В 1955 г. Адресном языке программирования (СССР) была введена «штрих-операция» (разыменование указателя), которая была аппаратно реализована Ф-операцией процессора в компьютере «Киев» (1955 г.), а позднее в компьютерах М-20, «Днепр», компьютерах семейства БЭСМ (БЭСМ-2, БЭСМ-3, БЭСМ-3М и БЭСМ-4), семейств «Минск» и «Урал», также и некоторых других компьютерах советского производства. Многократное применение разыменования указателя также было аппаратно реализовано в указанных компьютерах групповыми операциями модернизации адресов для ускорения работы с деревобразными форматами (списки и другие абстрактные типы данных являются частным случаем деревобразных форматов).

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

Пример работы с указателями в языке Си:

int  n  = 6;    // Объявление переменной n типа int и присваивание ей значения 6
int *pn = ( int * ) malloc( sizeof ( int ) ); // Объявление указателя pn и выделение памяти под int
    *pn = 5;    // Разыменование указателя и присваивание значения 5
     n = *pn;   // Присваивание n того значения (5), на которое указывает pn
     free(pn);  // Освобождение занятой памяти
     pn = &n;   // Присваивание указателю pn адреса переменной n (указатель будет ссылаться на n)
     n = 7;     // *pn тоже стало равно 7

Унарный оператор & возвращает адрес переменной, а оператор * используется для разыменования:

int sourceNum1 = 100;
int sourceNum2 = 200;
int* pNum1 = &sourceNum1;
int* pNum2 = &sourceNum2;
printf("Pointer value of 1-%d, 2-%d\n", *pNum1, *pNum2);  
pNum1 = pNum2;
printf("Pointer value of 1-%d, 2-%d\n", *pNum1, *pNum2);

В случае, если указатель хранит адрес какого-либо объекта, то говорят, что указатель ссылается или указывает на этот объект.

Языки, предусматривающие использование указателей для динамического распределения памяти, должны содержать оператор явного размещения переменных в памяти. В некоторых языках помимо этого оператора предусмотрен ещё и оператор явного удаления переменных из памяти. Обе эти операции часто принимают форму встроенных подпрограмм (функции malloc и free в Си, операторы new и delete в C++ и т. п.). При использовании простого, а не умного указателя следует всегда своевременно удалять переменную из памяти, дабы избежать утечки памяти.

Указатель на void

Указатель на тип void позволяет сослаться на любой тип данных, в том числе класс. Эта технология лежит в основе типа any библиотеки Boost.

class A {
    int field;
};

A clA;
void* pA = (void*)&clA; // указатель pA ссылается на объект класса А

Указатель на указатель (адресация высших рангов)

В программировании встречаются также указатели на указатели. Они хранят в себе адреса памяти, где находятся указатели на память, где расположен объект данных, или другой указатель. Цепочка из указателя, который указывает на указатель, позволяет ввести понятие многократного разыменования указателя (в Адресном языке программирования — «адресация высших рангов») и соответствующее действие над указателями.

int x, *p, **q;
x = 10;
p = &x;
q = &p; // указатель на указатель
printf ("%d", **q);

Нулевой указатель

Нулевой указатель — это указатель, хранящий специальное значение, показывающее, что данная переменная-указатель не ссылается (не указывает) ни на какой объект. В языках программирования он представлен особой константой[4]:

Основные проблемы применения

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

Для решения части проблем есть методы предохранения и страховки:

Инициализируйте указатели

Пример ошибки с неинициализированным указателем:

/* программа неверна. */
int main (void)
{
    int x, *p; // Выделилась память под x, но не под *p
    x = 10;    // В память записано 10
    *p = x;    // 10 записывается в неопределённое место в памяти, что может привести к аварийному завершению программы.
    return 0;
}

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

Используйте указатели правильно

Неправильное использование указателя:

#include <stdio.h>
/* программа неверна */
int main(void)
{
    int x, *p;
    x = 10;
    p = x;
    printf ("%d", *p);
    return 0;
}

Вызов printf() не выводит значения х, которое равно 10, на экран. Вместо этого выводится некоторое неизвестное значение — это результат неправильного использования оператора присваивания (р = х;). Этот оператор присваивает значение 10 указателю р, который должен содержать адрес, а не значение. К счастью, ошибка в данной программе обнаруживается компилятором — он выдаёт предупреждение о необычном преобразовании указателя. Для устранения ошибки следует написать p = &х;[6].

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

  • старайтесь инициализировать переменные сразу при объявлении (int x = 10;);
  • не смешивайте указатели с обычными переменными (например, int x, *p, y, *y_ptr;);
#include <stdio.h>
int main(void)
{
    int x = 10;
    int *p = &x;
    printf ("%d", *p);
    return 0;
}

Утечка памяти

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

char *pointer = NULL;
int i = 0;
for( i = 0; i < 10; i++ )
{
    pointer = (char *)malloc(100); // Память выделяет 10 раз
}
free(pointer); // А освобождается только в последнем случае

Сравнение указателей

Адреса в памяти, присвоенные указателям, можно сравнивать. Сравнения вида pNum1 < pNum2 и pNum1 > pNum2 часто используются для последовательного перебора элементов массива в цикле: pNum1 соответствует текущему положению в памяти, а pNum2 — концу массива. pNum1 == pNum2 вернёт истину в том случае, если оба указателя указывают на одну ячейку памяти.

Адресная арифметика

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

Типичные операции адресной арифметики:

int* p; // Допустим, p указывает на адрес 200
p++;    // После инкрементации она указывает на 200 + sizeof(int) = 204
p--;    // Сейчас она вновь указывает на 200.

Умный указатель

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

Примечания

  1. Videla, Alvaro Kateryna L. Yushchenko — Inventor of Pointers (англ.). https://medium.com/. A Computer of One’s Own Pioneers of the Computing Age (8 декабря 2018). Дата обращения: 30 октября 2020. Архивировано 23 сентября 2020 года.
  2. Для чего используются указатели? Дата обращения: 20 февраля 2013. Архивировано 26 февраля 2013 года.
  3. 14.1. Распределение памяти. — «Адрес начала выделенной памяти возвращается в точку вызова функции и записывается в переменную-указатель. Созданная таким образом переменная называется динамической переменной.» Дата обращения: 22 февраля 2013. Архивировано из оригинала 25 июня 2013 года.
  4. Question 5.1. comp.lang.c Frequently Asked Questions. Дата обращения: 20 февраля 2013. Архивировано 26 февраля 2013 года.
  5. A name for the null pointer: nullptr (англ.). JTC1.22.32. JTC1/SC22/WG21 — The C++ Standards Committee (2 октября 2007). Дата обращения: 4 октября 2010. Архивировано 11 февраля 2012 года.
  6. 1 2 3 Проблемы, связанные с указателями. Дата обращения: 22 февраля 2013. Архивировано 26 февраля 2013 года.

Read other articles:

This is a list of the tallest buildings and structures in the United Kingdom by usage. Tallest buildings Tallest castles Rank Building Location Image Height Year Notes 1 Warwick Castle Warwick, Warwickshire 45 m (148 ft) 1360 [1] Guy's tower rises 39 m (128 ft), Caesar's Tower rises 45 m (148 ft) but from a lower level. 2 Rochester Castle Rochester, Kent 38 m (125 ft) 1127 [2] 34.5 m (113 ft) to parapet, 38 m (125 ft...

 

Ilustrasi berbagai contoh baluster, dalam Buku Pegangan Ornamen, karya Franz S. Meyer Langkan adalah palang atau batang berbentuk vertikal, bujur sangkar, atau yang meliuk seperti mesin bubut - yang sering ditemukan pada tangga, parapet, dan bentuk arsitektur lainnya. Dalam konstruksi furnitur dikenal dengan istilah spindle. Bahan umum yang digunakan dalam konstruksinya adalah kayu dan batu jarang menggunakan logam atau keramik. Sekelompok baluster yang menyangga susuran tangga, koping, atau ...

 

Sushmita Sen Sushmita Sen (lahir 19 November 1975) adalah seorang model dan pemenang Miss Universe kontes 1994. Dia adalah wanita India pertama yang memenangkan gelar serta mahkota MISS UNIVERSE. Dia memulai kariernya dengan bermain film yang berbahasa Hindi, Dastak. Dia meraih gelar Filmfare Best Supporting Actress Award. Dia juga telah bertindak dalam film sukses secara komersial seperti Aankhen (2002),Main Hoon Na (2004),Maine Pyaar Kyun Kiya? (2005). Dia menerima pujian kritis di film sep...

Satelit komunikasi militer A.S. MILSTAR. Satelit komunikasi adalah sebuah satelit buatan yang ditempatkan di angkasa dengan tujuan telekomunikasi. Satelit komunikasi modern menggunakan orbit geosynchronous, orbit Molniya atau orbit Bumi rendah. Untuk pelayanan tetap, satelit komunikasi menyediakan sebuah teknologi tambahan bagi kabel komunikasi kapal selam optik fiber. Untuk aplikasi bergerak, seperti komunikasi ke kapal laut dan pesawat terbang, di mana aplikasi teknologi lain, seperti kabel...

 

Ice hockey team in Richmond, VirginiaRichmond RobinsCityRichmond, VirginiaLeagueAmerican Hockey LeagueOperated1971–1976Home arenaRichmond ColiseumAffiliatePhiladelphia FlyersFranchise history1928–1971Quebec Aces1971–1976Richmond Robins The Richmond Robins were a professional ice hockey team based in Richmond, Virginia. They were a member of the American Hockey League for five seasons from 1971–72 to 1975–76. Their cross-state rivals in the AHL were the Virginia Wings. The Robins wer...

 

1809 British military expedition to the Netherlands For the 1944 campaign, see Operation Infatuate. Walcheren CampaignPart of the War of the Fifth CoalitionIllness-stricken British troops evacuating the island of Walcheren on 30 August.Date30 July – 23 December 1809LocationWalcheren, Netherlands51°31′N 3°35′E / 51.52°N 3.58°E / 51.52; 3.58Result Franco-Dutch victory British forces withdrawBelligerents French Empire Kingdom of Holland United KingdomCommanders ...

Questa voce o sezione sull'argomento professionisti televisivi italiani non cita le fonti necessarie o quelle presenti sono insufficienti. Puoi migliorare questa voce aggiungendo citazioni da fonti attendibili secondo le linee guida sull'uso delle fonti. Giancarlo Magalli nel 2015 Giancarlo Magalli (Roma, 5 luglio 1947) è un autore televisivo, conduttore televisivo e attore italiano. Indice 1 Biografia 1.1 Carriera 1.2 Vita privata 2 Procedimenti giudiziari 3 Riconoscimenti 4 Televisio...

 

Yazdegerd IIIShahanshah dari ĒrānshahrKoin Yazdegerd III dari tahun terakhirnyaBerkuasa16 Juni 632 – 651PenobatanEstakhrPendahuluBorandukhtPenerusDihapuskanKelahiran624Kematian651 (usia 27)MervAyahShahriyarIbuTidak diketahuiAnakPeroz IIIIzdundad (Yazaddad)AgamaZoroastrianisme Yazdegerd III (bahasa Persia Pertengahan: 𐭩𐭦𐭣𐭪𐭥𐭲𐭩, Persia: یزدگرد Yazdākird, Arab:يزدجرد الثالث Yazdajird ats-Tsalits, Yunani: Izdegerdes), adalah penguasa ketiga puluh del...

 

† Человек прямоходящий Научная классификация Домен:ЭукариотыЦарство:ЖивотныеПодцарство:ЭуметазоиБез ранга:Двусторонне-симметричныеБез ранга:ВторичноротыеТип:ХордовыеПодтип:ПозвоночныеИнфратип:ЧелюстноротыеНадкласс:ЧетвероногиеКлада:АмниотыКлада:Синапсиды�...

Adam Baldwin Adam Baldwin (Chicago, 27 febbraio 1962) è un attore statunitense, noto per i ruoli di Animal in Full Metal Jacket, di Jayne Cobb in Firefly, di John Casey nella serie televisiva Chuck e di Mike Slattery nella serie The Last Ship. Indice 1 Biografia 2 Vita privata 3 Filmografia 3.1 Cinema 3.2 Televisione 4 Videogiochi 5 Doppiatori italiani 6 Altri progetti 7 Collegamenti esterni Biografia Nato a Chicago da una famiglia di origini irlandesi, dopo gli studi alla New Trier High Sch...

 

Disambiguazione – Se stai cercando altri significati, vedi Forte, Fortezza (disambigua) o Fortino (disambigua). Fortezza Vecchia di Livorno Una fortezza è una costruzione militare progettata con una funzione tattica difensiva. Le fortezze sono state utilizzate per migliaia di anni, in una varietà di forme sempre più complesse. Un'opera difensiva con caratteristiche simili alla fortezza, ma in genere con dimensioni inferiori, viene chiamata forte o fortino. Indice 1 Descrizione 2...

 

Questprobe Featuring The HulkvideogiocoSchermata su Commodore 64 (versione disco)PiattaformaAcorn Electron, Apple II, Atari 8-bit, BBC Micro, Dragon 32/64, Commodore 16, Commodore 64, MS-DOS, TI-99/4A, TRS-80, TRS-80 Color Computer, ZX Spectrum Data di pubblicazione1984 GenereAvventura testuale TemaFumetto Marvel Comics OrigineStati Uniti PubblicazioneAdventure International DesignScott Adams Modalità di giocoGiocatore singolo Periferiche di inputT...

Railway station in Cumbria, England DentGeneral informationLocationCowgill, South LakelandEnglandCoordinates54°16′57″N 2°21′49″W / 54.2825669°N 2.3635911°W / 54.2825669; -2.3635911Grid referenceSD764874Owned byNetwork RailManaged byNorthern TrainsPlatforms2Tracks2Other informationStation codeDNTClassificationDfT category F2HistoryOriginal companyMidland RailwayPre-groupingMidland RailwayPost-groupingLondon, Midland and Scottish RailwayBritish Rail (London M...

 

This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: 2007 Honda Grand Prix of St. Petersburg – news · newspapers · books · scholar · JSTOR (October 2023) (Learn how and when to remove this message) St. Petersburg Street Circuit The 2007 Honda Grand Prix of St. Petersburg was the second round of the 2007 IndyCar S...

 

Defunct Swedish newspaper Nya Dagligt AllehandaThe last edition of the Nya Dagligt Allehanda, 14 October, 1944TypeDaily newspaperFounded1859Political alignmentConservativeLanguageSwedishCeased publication1944HeadquartersStockholm This article is part of a series onConservatism in Sweden Ideologies Christian democracy Liberal Moderate Nationalist Principles Cameralism Duty Elitism Meritocracy Law and order Moderation Lagom Monarchism National romanticism Nationalism Folkhemmet Ordered liberty ...

Artikel ini mungkin mengandung riset asli. Anda dapat membantu memperbaikinya dengan memastikan pernyataan yang dibuat dan menambahkan referensi. Pernyataan yang berpangku pada riset asli harus dihapus. (Pelajari cara dan kapan saatnya untuk menghapus pesan templat ini) SMA Negeri 2 SurabayaInformasiDidirikan1 Agustus 1950AkreditasiANomor Statistik Sekolah301056009002Nomor Pokok Sekolah Nasional20532230Kepala SekolahDra. Titik Hariani, MMJurusan atau peminatanIPA dan IPSRentang kelasX MI...

 

Lincoln Memorial at Waterfront Park is a statue of Abraham Lincoln, depicted as he would have looked before he became President of the United States. The sculpture of him is bareheaded, seated on a rock with an open law book in one hand and the other in an outstretched, welcoming gesture.[1] The statue is located at Waterfront Park in Louisville, Kentucky.[2] The Lincoln Memorial in Louisville is part of the Lincoln Heritage Trail.[3] The statue and its accompanying b...

 

Revolutionary socialist women-of-color organization active from 1968 to 1980 A woman protesting during the black civil rights movement. The Third World Women's Alliance (TWWA) was a revolutionary socialist organization for women of color active in the United States from 1968 to 1980.[1] It aimed at ending capitalism, racism, imperialism, and sexism and was one of the earliest groups advocating for an intersectional approach to women's oppression. Members of the TWWA argued that women ...

Judo competition Judo Women's 57 kg at the 2011 World Judo ChampionshipsVenueAccor ArenaLocationParis, FranceDate24 August 2011 Competitors65 from 51 nationsMedalists  Aiko Sato (1st title)   Japan Rafaela Silva   Brazil Corina Căprioriu   Romania Kaori Matsumoto   JapanCompetition at external databasesLinksIJF • JudoInside← Tokyo 2010Rio de Janeiro 2013 → 2011 World Judo Champio...

 

For other people named Thomas Harris, see Thomas Harris (disambiguation). MI5 officer and art dealer (1908-1964) This biography may need cleanup. Please review the Manual of Style for biographies and help improve the article. (October 2018) This article needs additional citations for verification. Please help improve this article by adding citations to reliable sources. Unsourced material may be challenged and removed.Find sources: Tomás Harris – news · newspapers ...