Pointers C ++. Teil 1





указатели с++, указатели c++, new delete c++

Das Sammeln von Informationen für diesen Artikel, Ich erinnerte mich an meine erste Begegnung mit Zeigern – Trauer-Traurigkeit war… Deshalb wird nach ein paar Kapitel über das Thema aus verschiedenen Bücher über das Programmieren in C ++ lesen, es wurde beschlossen, einen anderen Weg zu gehen und das Thema C ++ Zeiger in der Sequenz vorhanden, die ich halte es für notwendig. geben Sie einfach eine kurze Definition und betrachten die Zeichen in – Beispiele. Im nächsten Artikel (Pointers C ++. Teil 2) Sie werden die Nuancen festgelegten, mit der Verwendung von Zeigern Profis in Si stile (Zeichen-Arrays) und Grund, dass wir sollten nicht vergessen,.

Pointer in C ++ – Variable, die speichert die Adresse eines Daten (Bedeutung) in-memory, und nicht die Daten selbst.

Betrachten Sie das folgende Beispiel, Sie werden die Haupt verstehen – Warum brauchen wir Indikatoren zu programmieren, wie zu deklarieren und zu verwenden.

Lassen Sie uns, im Programm benötigen wir ein Integer-Array zu erstellen, die genaue Größe, die nicht zu uns vor dem Start des Programms bekannt. Das heißt, wir wissen nicht, wie viele Zahlen der Benutzer in diesem Array zu machen müssen. natürlich, мы можем подстраховаться и объявить массив на несколько тысяч элементов (beispielsweise auf 5 000). Этого (по нашему субъективному мнению) должно хватить пользователю для работы. dass – действительноэтого может быть достаточно. Но не будем забывать, что этот массив займет в оперативной памяти много места (5 000 * 4 (тип int) = 20 000 Byte). Мы то подстраховались, а пользователь будет заполнять только 10 элементов нашего массива. Es stellt sich heraus,, что реально 40 байт в работе, und 19 960 байт напрасно занимают память.

В стандартную библиотечную функцию Größe von() передаем объявленный массив arrWithDigits Reihe 10. Она вернёт на место вызова размер в байтах, который занимает этот массив в памяти. На вопросСколько чисел вы введете в массив?” ответим – 10. On line 15, Ausdruck Menge * Größe von(int) wäre gleichbedeutend mit 10 * 4, так как функция Größe von(int) Rückkehr 4 (размер в байтах типа int). Далее введем числа с клавиатуры и программа покажет их на экран. Es stellt sich heraus,, что остальные 4990 элементов будут хранить нули. Так что нет смысла их показывать.

C ++ Zeiger, c ++ Zeiger, neu, löschen

Главная информация на экране: массив занял 20 000 Byte, а реально для него необходимо 40 Byte. Как выйти из этой ситуации? vielleicht, кому-то захочется переписать программу так, чтобы пользователь с клавиатуры вводил размер массива и уже после ввода значения объявить массив с необходимым количеством элементов. Но это невозможно реализовать без указателей. Wie Sie erinnern sich vielleicht, – размер массива должен быть константой. То есть целочисленная константа должна быть инициализирована до объявления массива и мы не можем запросить её ввод с клавиатуры. Поэкспериментируйтепроверьте.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

указатели с++, указатели c++, new, delete
Тут нам подсвечивает красным оператор >> так как изменять константное значение нельзя.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

указатели с++, указатели c++, new, delete
Тут нас предупреждают о том, что размером массива НЕ может быть значение обычной переменной. Необходимо константное значение!

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

В следующем коде мы будем использовать указатель и новые для вас операторы neu (выделяет память) und löschen (освобождает память).

Пользователь вводит значение с клавиатуры – Reihe 12. Ниже определён указатель: int* arrWithDigits Dieser Eintrag bedeutet,, dass arrWithDigits это указатель. Он создан для хранения адреса ячейки, в которой будет находиться целое число. In diesem Fall arrWithDigits будет указывать на ячейку массива с индексом 0. Знак * тот же что применяется при умножении. По контексту компиляторпоймет”, что это объявление указателя, а не умножение. Далее следует знак = и оператор neu, который выделяет участок памяти. Мы помним, что у нас память должна быть выделена под массив, а не под одно число. Запись neu int [sizeOfArray] можно расшифровать так: neu (выдели память) int (Lagerung ganzen Zahlen) [sizeOfArray] (в количестве sizeOfArray).

Таким образом в строке 16 был определён dynamisches Array. Das heisst, что память под него выделится (или не выделится) во время работы программы, а не во время компиляции, как это происходит с обычными массивами. То есть выделение памяти зависит от развития программы и решений, которые принимаются непосредственно в её работе. In diesem Fall – зависит от того, что введёт пользователь в переменную sizeOfArray

On line 25 применяется оператор löschen. Он освобождает выделенную оператором neu память. Als neu выделил память под размещение массива, то и при её освобождении надо дать понять компилятору, что необходимо освободить память массива, а не только его нулевой ячейки, на которую указывает arrWithDigits. Поэтому между löschen и именем указателя ставятся квадратные скобки [] – löschen [] arrWithDigits; Denken Sie daran,, что каждый раз, когда выделяется память с помощью neu, необходимо эту память освободить используя löschen. natürlich, по завершении программы память, занимаемая ей, будет автоматически освобождена. Но пусть для вас станет хорошей привычкой использование операторов neu und löschen в паре. Ведь в программе могут располагаться 5-6 массивов например. И если вы будете освобождать память, каждый раз, когда она уже не потребуется в дальнейшем в запущенной программепамять будет расходоваться более разумно.

Допустим в нашей программе мы заполнили массив десятью значениями. Далее посчитали их сумму и записали в какую-то переменную. И всёбольше мы с этим массивом работать уже не будем. Программа же продолжает работу и в ней создаются новые динамические массивы для каких-то целей. В этом случае целесообразно освободить память, das belegt die erste Reihe. Тогда при выделении памяти под остальные массивы эта память может быть использована в программе повторно.

Рассмотрим использование указателей, как параметров Funktion. Für den Anfang, наберите и откомпилируйте следующий код. В нем функция получает две переменные и предлагает внести изменения в их значения.

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

C ++ Zeiger, c ++ Zeiger, neu, löschen

Wie Sie erinnern sich vielleicht,, функция работает не на прямую с переменными, а создает их точные копии. Эти копии уничтожаются после выхода из функции. То есть функция получила в виде параметра какую-то переменную, создала её копию, поработала с ней и уничтожила. Сама переменная останется при этом неизменной.

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

В заголовке (Reihe 27) и прототипе функции (Reihe 5), добавляем операцию * перед именами параметров. Это говорит о том, что функция получит адреса, а не значения переменных. При вызове функции из Main() добавляем перед именами передаваемых переменных операцию & (Ampersand – Verschiebung + 7). & означает взятие адреса. Вы помните, что указатель хранит адрес. Поэтому мы не можем передать обычное значение, если в заголовке указано, что функция примет указатель. Используя & перед именами переменных, функция получит их адреса.

В теле функции, при вводе значений в переменные, необходимо использовать разыменование указателей. Делается это с помощью всё той же операции * : Gin >> *varForCh1; Так мы внесем изменения в значения переменных, а не в адреса. Проверим работу программы:

C ++ Zeiger, c ++ Zeiger, neu, löschen

Всё получилосьзначения переменных были изменены в функции.

Такой способ (передача параметров в функцию через указатель) широко использовался в программировании на C. В C++ всё чаще используют передачу параметров в функцию по ссылке. Там отпадает необходимость использовать разыменование * и взятие адреса & Variablen. Поэтому использовать передачу параметров по ссылке удобней. Этот способ мы с вами рассмотрим в следующих уроках.

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

По возможности посмотрите видео об указателях (mit einer 12-minütigen):

Parameter (Argumente) Funktion:




Abonnieren Sie neue Beiträge auf unserer Seite Ankündigung:


Ich bin damit einverstanden, Nachrichten zu empfangen von purecodecpp.com auf meine E-Mail

Datum
Seite
Pointers C ++. Dynamische Arrays C ++
Wertung
5

7 Gedanken zu "Pointers C ++. Teil 1

  1. Примерно на 45-ой минуте 8-го урока говорится, что если не использовать константу, то по любому только выделять память через new. Но во время этого я подумал, что дело решается ещё одной переменной.
    int N;
    Gin>>N;
    const int M=N;
    int d[M];

    für (int i = 0;ich!=M;i ++)
    {
    d[ich] = i;
    cout <<d[ich]<<endl;
    }

    И это у меня вполне компилируется.

    1. Вы могли бы и не присваивать M=N, а просто написать: int d[N].
      Но это не противоречит ничему сказанному – Das расширение стандарта C++, пришедшее из стандарта C99 языка C (wie Sie sehen können, всё это стандарты самых последних лет!), и называется это VLA (Variable Legth Array).
      Это расширение позволяет создавать локальные внутри функции массивы с динамически определяемыми размерами. При этом массив создаётся в стеке вызываемой функции. Im Prinzip, в C был и раньше скрытый способ делать то же самое с помощью вызова:

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

      1. Спасибо за подробные разъяснения. Я присваивал М = N из-за того, что автор видео показал, как напрямую, если не использовать ключевое слово const, не компилируется. А я сразу решил проверить, но немного по другому. übrigens, в компиляторе давно я указывал с++11.

  2. Парадокс!!!
    Компиляторcompiler: GNU GCC Compilerпринял следующий код:

    #einschließen
    #einschließen

    using namespace std;

    int main()
    {
    setlocale(LC_ALL, “Russisch”);

    int SizeOfArray;
    cout << "Сколько чисел вы введёте в массив? " <> SizeOfArray;
    int arrWithDigits[SizeOfArray] = {};

    für (int i = 0; ich < SizeOfArray; i ++)
    {
    cout << ich + 1 <> arrWithDigits[ich];
    }
    cout << endl;

    für (int i = 0; ich < SizeOfArray; i ++)
    {
    cout << setw(3) << arrWithDigits[ich] << " |";
    }
    cout << endl;
    Rückkehr 0;
    }

    Programm, в которой работаю Code::Block 16.01.
    ————– Build: Debug in Zadacha12 (compiler: GNU GCC Compiler)—————

    mingw32-g++.exe -Wall -g -c C:\2\codeblocks-16.01\Code\Zadacha12\Zadacha12.cpp -o obj\Debug\Zadacha12.o
    mingw32-g++.exe -o bin\Debug\Zadacha12.exe obj\Debug\Zadacha12.o
    Output file is bin\Debug\Zadacha12.exe with size 1,01 MB
    Process terminated with status 0 (0 minute(s), 0 zweite(s))
    0 Fehler(s), 0 warning(s) (0 minute(s), 0 zweite(s))

    1. Парадокс то в чём?
      Компилятор GCC намного совершеннее компилятора от Microsoft, и гораздо точнее в синтаксисе соответствует стандартам языка C++.

Hinterlasse eine Antwort

Platz Code in Tags: <pre class="lang:c ++ dekodieren:true ">DEIN CODE</Vor>