Collecting information for this article, I remembered my first encounter with pointers– sadness-sadness was… Therefore, after reading a few chapters on the topic from different books about programming in C ++, it was decided to go another way and present the topic C ++ pointers in the sequence, which I consider it necessary. Immediately give you a short definition and will consider pointers in work – on examples. In the next article (C++ Pointers. Part 2) will set out the nuances of, with the use of pointers C-style strings (character arrays) and basic, what you should remember.
Pointer in C ++ – variable, that in itself stores the address data (the value of the) in memory, and not the data itself.
Having considered the following examples, you'll see the main – Why do we need programming pointers, how to declare and use.
Let's, in the program we need to create an integer array, the exact size of which is not known to us before the start of the program. That is, we do not know how many numbers the user will need to make in this array. Of course, we can insure and declare an array of several thousand items (for example on 5 000). This (in our subjective opinion) it should be enough for the user to work. Yes – really – This may be sufficient. But let's not forget, that the array will take up much space in RAM (5 000 * 4 (type int) = 20 000 bytes). We then secured themselves, and the user will fill only 10 elements of our array. It turns out, what is real 40 bytes in the work, and 19 960 byte needlessly take up memory.
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 27 28 29 30 | #include <iostream> using namespace std; int main() { setlocale(LC_ALL, "rus"); const int SizeOfArray = 5000; int arrWithDigits[SizeOfArray] = {}; cout << "Массив занял в памяти " << sizeof(arrWithDigits) << " байт" << endl; int amount = 0; cout << "Сколько чисел вы введёте в массив? "; cin >> amount; cout << "Реально необходимо " << amount * sizeof(int) << " байт" << endl; for (int i = 0; i < amount; i++) { cout << i + 1 << "-е число: "; cin >> arrWithDigits[i]; } cout << endl; for (int i = 0; i < amount; i++) { cout << arrWithDigits[i] << " "; } cout << endl; return 0; } |
The standard library function sizeof() send an announcement to the array arrWithDigitsstring 10. She will return to the place of call size in bytes, which takes the array in memory. On the question “How many numbers you enter into an array?” answer – 10. In string 15, expressionamount * sizeof(int) would be equivalent to 10 * 4, since the function sizeof(int) return 4 (the size, in bytes, of type int). Next, enter the number from the keyboard and the program will show them on the screen. It turns out, that the remaining 4990 elements will keep the zeros. So it makes no sense to them to show.
Home information on the screen: an array of finished 20 000 bytes, but really it is necessary to 40 bytes. How to get out of this situation? Perhaps, someone wants to rewrite the program so, the user with the keyboard input of the array, and after entering a value to declare an array with the required number of elements. But it is impossible to implement without pointers. As you remember – size of the array must be a constant. That is, an integer constant must be initialized to an array of ads and we can not ask for her input from the keyboard. Experiment – check.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In the next example we will use a pointer and new operators for you new (allocate memory) and delete (frees memory).
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 27 | #include <iostream> #include <clocale> using namespace std; int main() { setlocale(LC_ALL, "rus"); int sizeOfArray = 0; // размер массива (введет пользователь) cout << "Чтобы создать массив чисел, введите его размер: "; cin >> sizeOfArray; // ВНИМАНИЕ! int* arrWithDigits - объявление указателя // на участок памяти, которую выделит new int* arrWithDigits = new int [sizeOfArray]; for (int i = 0; i < sizeOfArray; i++) { arrWithDigits[i] = i + 1; cout << arrWithDigits[i] << " "; } cout << endl; delete [] arrWithDigits; // освобождение памяти return 0; } |
The user enters a value from the keyboard – string 12. Below defined pointer: int* arrWithDigits This entry means, whatarrWithDigits– this pointer. It is designed to store cell addresses, which will be an integer. In our case arrWithDigits will point to an array of cell index 0. Sign * – the same that is used for multiplication. In the context of the compiler “understand”, what is the declaration of a pointer, instead of multiplication. This is followed by the sign = and operator new, which allocates memory section. We remember, that our memory should be allocated for the array, and not a single number. Record new int [sizeOfArray] so you can decipher: new (Mark memory) int (to store integers) [sizeOfArray] (in an amount sizeOfArray).
Thus, in string 16 was determined dynamic array. It means, that memory is allocated for it (or does not stand out) during the program, and not at compile time, as is the case with conventional arrays. That is, memory allocation depends on the development of programs and solutions, which are taken directly to her work. In our case – depends on, that will introduce the user to the variablesizeOfArray
In string 25 apply statement delete. He frees the allocated operator new memory. So as new it allocates memory for an array of accommodation, even if its release is necessary to make it clear to the compiler, it is necessary to release the array memory, and not just the zero cell, which indicates arrWithDigits. Therefore, between delete and the name of the pointer are square brackets [] – delete [] arrWithDigits; You should remember, that every time, When memory is allocated by anew, you must release the memory using delete. Of course, at the end of program memory, occupied it, will be automatically freed. But even for you will become a good habit to use statements new and delete in pair. Because the programme can be 5-6 arrays for example. And if you will free the memory, everytime, when it is no longer required in the future in the running program – the memory will be spent more wisely.
Let's say in our program we filled the array with ten values. Next, find them, and the amount recorded in some variable. And all – the more we work with the array will no longer be. The program also continues to work, and new dynamic arrays are created in it for some purposes. In this case it is advisable to release memory, which occupies the first array. Then, when the memory allocation for the rest of this memory arrays can be used to re-program.
Consider the use of pointers, as a parameter function. For the beginning, enter and compile the following code. It receives two function variables and proposes changes in their values.
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 27 28 29 30 31 32 33 | #include <iostream> #include <clocale> using namespace std; void changeData(int varForCh1, int varForCh2); int main() { setlocale(LC_ALL, "rus"); int variableForChange_1 = 0; int variableForChange_2 = 0; cout << "variableForChange_1 = " << variableForChange_1 << endl; cout << "variableForChange_2 = " << variableForChange_2 << endl; cout << endl; changeData(variableForChange_1, variableForChange_2); cout << endl; cout << "variableForChange_1 = " << variableForChange_1 << endl; cout << "variableForChange_2 = " << variableForChange_2 << endl; return 0; } void changeData(int varForCh1, int varForCh2) { cout << "Введите новое значение первой переменной: "; cin >> varForCh1; cout << "Введите новое значение второй переменной: "; cin >> varForCh2; } |
Run the program and enter the new values of the variables. You will see in the end, that at the end of the function, variables have not changed and are 0.
As you remember, function does not work directly with variables, and create their replicas. These copies are destroyed after leaving the function. That is the function received as a parameter some variable, has created its copy, has worked with it and destroyed. The very variable remains unchanged in this case.
Using pointers, we can pass variables into the function address. Then the function will be able to work directly with these variables at. Make any changes to the previous program.
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 27 28 29 30 31 32 33 | #include <iostream> #include <clocale> using namespace std; void changeData(int* varForCh1, int* varForCh2); int main() { setlocale(LC_ALL, "rus"); int variableForChange_1 = 0; int variableForChange_2 = 0; cout << "variableForChange_1 = " << variableForChange_1 << endl; cout << "variableForChange_2 = " << variableForChange_2 << endl; cout << endl; changeData(&variableForChange_1, &variableForChange_2); cout << endl; cout << "variableForChange_1 = " << variableForChange_1 << endl; cout << "variableForChange_2 = " << variableForChange_2 << endl; return 0; } void changeData(int* varForCh1, int* varForCh2) { cout << "Введите новое значение первой переменной: "; cin >> *varForCh1; cout << "Введите новое значение второй переменной: "; cin >> *varForCh2; } |
In the header (string 27) and the function prototype (string 5), add operation* before the parameter names. This suggests that the, the function will receive the address of, rather than the values of the variables. When calling a function of the main() add to the names of variables transmitted operation& (ampersand – Shift + 7). & means taking the address. You remember, pointer stores the address. Therefore, we cannot pass the ordinary meaning, if the header specified, that the function takes a pointer. Using & before the variable names, function get their addresses.
The body of the function, when entering values in variables, you must use the pointer dereference. This is done using all the same operation * : cin >> *varForCh1; So we will make changes in the values of the variables, and not in the address. Check the operation of the program:
Everything worked out – variables were changed in the function.
This way of (passing parameters to the function through a pointer) widely used in programming C. In C ++, are increasingly using the transmission parameters in the link function. There is no need to use the dereference * and taking the address & variables. Therefore, use the convenient link to pass parameters. The method we'll look at in the following lessons.
Do not worry, if something is not clear. You got a lot of new information in this lesson – and it is quite normal, not all at once perceive. Understanding pointers will come with practice. We still talk about pointers in the second part of this article and we will solve the tasks. So everything will be fine.
If possible, watch the video about pointers:
At about the 45th minute of the 8th lesson says, that if you do not use the constant, then for any memory to allocate only through new. But at the time, I thought,, that the case is solved another variable.
int N;
cin>>N;
const int M=N;
int d[M];
for (int i = 0;i!=M;i )
{
d[i] = i;
cout <<d[i]<<endl;
}
And this I have compiled quite.
You could not assign M = N, just write: int d[N].
But this does not contradict what has been said nothing – this is expansion Standard C ++, came from the standard C99 C language (as you can see, all these standards are the most recent years!), and it is called VLA (Variable Legth Array).
This extension allows you to create local within the function arrays with dynamically determined by the size. This array is created the stack the called function. Basically, in C was previously hidden way to do the same by calling:
int *d = (int*)alloca( N * sizeof( int ) );
Use VLA need, Nevertheless, carefully:
– it is compiled only if you installed the compiler options to the new standards;
– This innovation is a lot of controversy, and it can be reversed in future standards.
Thanks for the detailed explanation. I am assuming M = N because, that the author of the video showed, both directly, if you do not use the const keyword, not compiled. And I just decided to check out, but a little differently. By the way, compiler for a long time, I pointed out to ++ 11.
Cm. : https://purecodecpp.com/archives/3205
Array takes your memory, dynamic array works as a normal, Now only the memory then is cleared, in large projects it is very useful
It is very doubtful statement!
An array of locally declared (in function) It is placed on the stack and is cleared by the end of the function. Especially after the resolution is effectively arrays with dynamic boundaries C ++ 11 standard.
And the use of dynamically allocated arrays, under certain merits, It has even more disadvantages.
Paradox!!!
Compiler “compiler: GNU GCC Compiler” I adopted the following code:
#include
#include
using namespace std;
int main()
{
setlocale(LC_ALL, “Russian”);
int SizeOfArray;
cout << "Сколько чисел вы введёте в массив? " <> SizeOfArray;
int arrWithDigits[SizeOfArray] = {};
for (int i = 0; i < SizeOfArray; i )
{
cout << i + 1 <> arrWithDigits[i];
}
cout << endl;
for (int i = 0; i < SizeOfArray; i )
{
cout << setw(3) << arrWithDigits[i] << " |";
}
cout << endl;
return 0;
}
Program, in which the working Code::Block 16.01.
————– Build: Debug in Zadacha12 (compiler: GNU GCC Compiler)—————
mingw32-g++.exe -Wall -g -c C:\2\codeblocks-16.01CodeZadacha12Zadacha12.cpp -o objDebugZadacha12.o
mingw32-g++.exe -o binDebugZadacha12.exe objDebugZadacha12.o
Output file is binDebugZadacha12.exe with size 1,01 MB
Process terminated with status 0 (0 minute(s), 0 second(s))
0 error(s), 0 warning(s) (0 minute(s), 0 second(s))
The paradox is what?
GCC compiler is much more perfect than the compiler from Microsoft, and much more precise in the syntax complies with the C ++ language.
nor of the stack, not the dog, сразу @int* prt= new int;@. brilliantly. especially the lack of a clear description about the ampersand pleased. once the code you half a page.
To discuss and understand the signs of any stack, or a bunch of, as a concept, and the gift is not necessary.
“… you just do not know how to cook them”.
during the whole study c ++ asked yourself – how to enable a user to define the number of elements in the array. That only did not try. And then a lesson on this topic. Thank you!
good afternoon. The topic description says that, for, to pass an address to a function, for example, to function F(&a) , then you need to apply the operand & to take the address, and at the input of the function declare a pointer F(int * p), but why the following code worked?
void swap (int * a, int *b) {
….
}
….
int a = 5;
int b = 10;
swap(a,b); <- – – in fact, the values of these variables were transferred, but the function took their address and allowed them to change.
The program was written in the online compiler REPL it , about this I have a question, we should always use when transferring data to a function &?
Why the program was compiled, online compiler features?
And if so
//———————————————-
#include
using namespace std;
int main()
{
int a;
cin >> a;
const int b = a;
int c[b];
return 0;
}
//——————————–
It seems to work
Функция swap(изменение чисел местами с объяснением). За пример взяты числа 2 and 3.
void swap(int* p, int* q) // p = 2, q = 3
{
int temp{};
temp = *p; // temp = 0, p = 2; temp = 2, p = 2
*p = *q; // p = 2, q = 3; p = 3, q = 3
*q = temp; // temp = 2, q = 3; temp = 2, q = 3
temp = NULL; // p = 3, q = 2
}
*q = temp; // temp = 2, q = 3; q = 2, temp = 2