catalogue
18.1} what is stored in the variable
18.2 how to use variables in programs
19. Pointer movement and data type
21. Use the new keyword to allocate memory space
22. Use delete to free memory space
23. Dynamically create and release arrays
24. Use dynamically created arrays
26. Constant pointer and pointer constant
27. Use new to dynamically create a structure
28. Use new to dynamically create a common body
29. Multi dimensional array and multi-level pointer
30.vector template class foundation
The difference between array and array template
18. Pointer Foundation
18.1} what is stored in the variable
Variables are stored in memory space.
int n = 100; float value = 123.321; cout << "n = " << n << endl; // 100 cout << "n address = " << &n << endl; // 0x7fff5fbffb4c each hexadecimal number represents a 4-bit binary number /* In fact, for a 64 bit system, the address should be 64 bit binary, that is, 8 bytes, and the full version of the address should be 0x00007fff5fbffb4c, except that the previous zeros are omitted*/ // That is, 16 bit hexadecimal < = = > 64 bit binary, and two bit hexadecimal number (corresponding to 8-bit binary number) represents 1 byte /* Note: 1-bit hexadecimal number is different from 16 bit binary number. 1-bit hexadecimal number corresponds to 4-bit binary number, which is a half byte, and 16 bit binary corresponds to 2 bytes */ // For 32-bit systems, the address should be 32-bit binary, corresponding to 4 bytes cout << "value = " << value << endl; // 123.321 cout << "value address = " << &value << endl; // 0x7fff5fbffb28, the preceding 0000 is omitted
//Error report: long type and pointer type occupy the same space, but they cannot be assigned directly long pointer = &value; long pointer = long(&value); cout << "pointer = " << pointer << endl;//The decimal number 140734799805208 is the decimal version of the hexadecimal address value
18.2 how to use variables in programs
// Purpose of pointer int abc[10] = {1}; // Save up to 10 abc[123] = 3; // The memory is exceeded, but it is allowed in C + +, but it may crash the program int abc[200] = {1}; // This can prevent the program from crashing, but it wastes memory. Pointers can solve this problem abc[123] = 3; int *pn = &n; // Define pointer variables float *pvalue = &value; // Defines a pointer to a variable of type float cout << "pn = " << pn << endl; // Output address in hexadecimal mode cout << "pvalue = " << pvalue << endl; cout << "*pn = " << *pn << endl; // 100 cout << "*pvalue = " << *pvalue << endl; // 123.321 cout << sizeof(*pn) << endl; // 4 //Pointer itself is a value of long type, which can be cast to pointer type through (float *) cout << "*pvalue = " << *((float*)pointer) << endl; // 123.321
19. Pointer movement and data type
int numbers[2] {25,26}; // int *numbers; The default is to point to the first number of the array: numbers[0], numbers[1] cout << "numbers[0]=" << *numbers << endl; // 25 cout << "numbers[1]=" << *(numbers+1) << endl; // 26 char chars[2] {25, 26}; cout << "chars[0]=" << int(*chars) << endl; // 25 cout << "chars[1]=" << int(*(chars+1)) << endl; // 26 void *p = numbers; cout << "chars[1]=" << int(*(p+1)) << endl; // report errors
25 corresponding binary: 11001
26 corresponding binary: 11010
Variables of type int occupy 4 bytes in memory, 8 bits per byte, a total of 32 bits. char type variables occupy 1 byte in memory,
When pointing to a variable of type int + 1, the pointer moves 4 bytes; when pointing to a variable of type char + 1, the pointer moves 1 byte
void *p = numbers; cout << "chars[1]=" << int(*(p+1)) << endl; // report errors Because the pointer points to void Type. This is an uncertain type. The pointer does not know how many bits to move, so an error will be reported If you want to move the pointer, you need to specify the data type pointed to by the pointer
20. Pointer initialization
int xyz = 30; int *p; cout << "p address=" << p << endl; // Print 0x0 int xyz = 30; int *p = &xyz; cout << "p address=" << p << endl; // 0x7fff5fbffb4c p = &xyz; *p = 123; cout << "xyz = " << xyz << endl; // 123 xyz = 456; cout << "*p = " << *p << endl; // 456
21. Use the new keyword to allocate memory space
int xyz = 100; int *p = &xyz; // Initializing the pointer also requires a separate variable to be defined, which is relatively troublesome // In C language, malloc can be used to allocate memory space. C + + can also be used, but new is better // typename *pointer = new typename int *pointer = new int; // A 4-byte memory space is allocated, and the first address of the memory space is assigned to the pointer *pointer = 123; cout << "*pointer=" << *pointer << endl; // 123 // distinguish: int xyz = 100; // 4 bytes of memory space is allocated, and the memory space is named xyz int *pointer = new int; /* The allocated memory space is not named, so the memory space allocated by new cannot be used by name. The only way to use the memory space is to use the pointer pointing to the first address of the memory space. Pointer is the name of the first address of the memory space, and xyz is the name of the whole memory space */ double *value = new double; *value = 33.22; cout << "*value=" << *value << endl; // 33.22 // If new fails to allocate memory space, an exception will be thrown
22. Use delete to free memory space
/* 1. delete Only the memory space allocated with new can be released, and the memory space allocated with malloc and similar functions cannot be released 2. The common variable system will automatically reclaim the occupied memory space, but the system will not automatically reclaim the dynamically allocated memory space (on the heap) such as new and malloc 3. delete After that, the data of the pointer itself and the memory space pointed to by the pointer will not be cleared unless the data is written again 4. Multiple pointers point to the same memory space. As long as one pointer is released, the others will be released 5. The memory space pointed to by the pointer that has been released cannot be released again. */ int *n = new int; *n = 123; cout << "n address before delete:" << n << endl; // 0x100103a40 // 1 2 delete n; // No* int xyz = 300; cout << "n address after delete:" << n << endl; // 0x100103a40 cout << "n = " << *n << endl; // 123 // 3 // When using new to dynamically allocate memory space, a flag will be given on the memory space, indicating that the memory space will not be allocated to any other variables. Using delete means that the flag is cleared, and the memory space may be allocated to other variables at any time *n = 456; /* Try not to use it like this. Although the data in this memory space is still there, the space has been released and may be occupied by other variables at any time */ cout << "n = " << *n << endl; // 456 int xyz = 300; n = &xyz; // There is no problem with this, because xyz is on the stack // 4 int *m = new int; *m = 444; int *p = m; // p and m point to the same memory space with a length of 4 bytes delete p; // Equivalent to releasing m // 5 delete p; // Throw exception delete m; // Throw exception
23. Dynamically create and release arrays
int n = 20; int array1[10]; // The array length needs to be specified when defining int array2[n]; int *array3 = new int[n]; int *array4; array4 = new int[100]; //array4 = new int[200]; /* This will cause memory leakage because new int[100]; If the memory space of is not released, a new space is defined, which will result in that the original 400 bytes of memory space will not be allocated to any variables. Even if the program exits, the memory space will not be released*/ delete [] array4; // array4 = new int[200] / / no problem // array4 = NULL; // 0, set the pointer variable / array to null, and you'd better add this after delete array4 = nullptr; // Try to use nullptr instead of NULL in c++ 11 int *p = new int; delete p; p = nullptr; // It is best to set the pointer to null after delete array4 = new int[200];
24. Use dynamically created arrays
int *array = new int[10]{1,2}; // Allocated space to store 10 int type values, and initialized the first two array elements array[2] = 30; // You can also assign a value to an array element separately array[3] = 50; cout << "array[0]=" << array[0] << endl; // 1 cout << "array[3]=" << array[3] << endl; // 50 // Reference array elements using pointers cout << "array[2]=" << *(array + 2) << endl; // 30 int codeArray[3]{10,20, 30}; cout << "codeArray[0] = " << codeArray[0] << endl; // 10 cout << "codeArray[1] = " << *(codeArray + 1) << endl; // 20 cout << "codeArray[2] = " << *(codeArray + 2) << endl; // 30 array++; cout << "array[1]=" << *array << endl; // 2 array--; // It also refers back to the first address of the storage space codeArray++; // An error is reported, which is not allowed. For non pointer arrays, self addition or self subtraction cannot be used // Free memory space for array delete [] array; array = nullptr;
25. Pointer and string
char str[10] = "hello"; // String defined cout << str << endl; // hello int pp = 3; char *p_str = "hello"; //This definition is not recommended. It is equivalent to a string pointer to a constant character. Each character cannot be modified cout << p_str << endl; // hello char *p = str; // p points to str. if STR is modified, p will also be modified cout << p << endl; /* Print the hello. Note that the address of h is not output here, but the whole hello. Because the I/O class in the C + + standard library overloads the < < operator, it will be treated as a string name when encountering a character pointer, and the string referred to by the pointer will be output */ p = new char[strlen(str) + 1]; // Allocate a space for the string terminator strcpy(p, str); /* The function will automatically add an end character. The first parameter is the first address of the target memory space, and the second parameter is the address of the content to be copied */ str[1] = 'x'; cout << str << endl; // hxllo *(p + 2) = 'w'; // p refers to the new memory space. After str is modified, p will not be affected cout << p << endl; // hewlo char *p_str = "hello"; //It is equivalent to a string pointer pointing to constant characters. Each character cannot be modified. This is not recommended *p_str = 's'; // report errors delete [] p; delete [] p_str; // An error is reported. delete [] can only free the memory space allocated by new
26. Constant pointer and pointer constant
26.1 constant pointer
// const pointer const int code = 1234; // Constants must be initialized when defined // code = 3; // An error is reported and cannot be changed. The constant is allocated on the stack. It is read-only and cannot be changed const int numbers[] = {1,2,3,4}; // numbers[2] = 44; // report errors const int *p = new int(100); // Constant pointers are usually initialized at declaration time // *p = 333; // An error is reported. The constant pointer points to a constant. It is not allowed to change the value it points to through this pointer cout << *p << endl; char str[10] = "hello"; const char *p_str = str; // A constant pointer to a string does not allow characters to be modified // str can be changed, but * p_str cannot be changed //*p_str = 'a'; // Error report, p_str is a constant pointer. It is not allowed to change the value it points to through this pointer
26.2 pointer constants
char * const p_str1 = str; *p_str1 = '1'; // Can change p_str1 = new char[3]; // An error is reported. The pointer cannot point to the new memory space const char * const p_str1 = str; *p_str1 = '1'; // report errors p_str1 = new char[3]; // An error is reported. The pointer cannot point to the new memory space
27. Use new to dynamically create a structure
#include <iostream> using namespace std; int main(int argc, const char * argv[]) { // Create structure object ① ② with new struct MyStruct { int code; char *name; double price; }; MyStruct *p = new MyStruct(); // Use '- >' when accessing structure members with structure pointers p->name = "abc"; /* An error is reported. Name itself is a character pointer, so new MyStruct() only allocates pointer sized memory to name. The memory pointed to by name has not been allocated, so it is necessary to allocate memory to the place pointed to by name */ p->name = new char[30]; // A total of 30 character size / type data can be stored, ② strcpy(p->name, "iPhone6 plus 256G"); (*p).code = 1234; // Another way to access members using structure pointers p->price = 9999; cout << "p->name = " << p->name << endl; // iPhone6 plus 256G cout << "(*p).code = " << (*p).code << endl; // 1234 cout << "p->price = " << p->price << endl; // 9999 return 0; }
28. Use new to dynamically create a common body
union MyUnion { int code1; long code2; }; MyUnion *p = new MyUnion(); // Using new to dynamically create a common body p->code1 = 200; cout << "p->code1 = " << (*p).code1 << endl; // 200 cout << "p->code2 = " << (*p).code2 << endl; // 200 (*p).code2 = 400; cout << "p->code1 = " << p->code1 << endl; /* 400,As long as the number set is less than the range of int, code1 and code2 are equal */
29. Multi dimensional array and multi-level pointer
29.1 multidimensional array
int codes1[10] = {1,2,3}; // One dimensional array int codes2[5][10]; // Two dimensional array /* Use a one-dimensional array to represent a two-dimensional array: find the index of codes1[8] in codes2[5][10]: Rounding calculation row index rounding calculation column index: 8 / 5 = 1 (row 2, index starts from 0) 8% 5 = 3 (column 4, index starts from 0). Therefore, the two-dimensional array index corresponding to codes1[8] is codes1[1][3] Calculate one-dimensional array index from two-dimensional array: codes1 [1] [2] 1 * 5 + 2 = 7 = codes1 [7] */ // One dimensional array initialization method: the first element in the second row of initialization is 123 int codes2[5][10] = {1,2,3,4,5,6,7,8,9,0,123/*codes2[1][0]*/}; // The first ten have to "run with me", which is very troublesome cout << "codes2[1][0] = " << codes2[1][0] << endl; // 123 // Initialization method of two-dimensional array - initialize the 10th element in line 5 to 200 int codes2[5][10] = {{1,2},{4,5},{},{},{1,2,3,4,5,6,7,8,9,200}}; cout << "codes2[4][9] = " << codes2[4][9] << endl; // 200 // The three-dimensional array initializes five channels, 10 rows and 100 columns, that is, five 10x100 two-dimensional arrays int codes3[5][10][100] = {{{1,2}/*The first two column elements (100 columns in total) of the first row of the first channel of codes3 are initialized, codes3[0][0] [...]*/,{4,5}/*The first two column elements (100 columns in total) of the second row of the first channel of codes3 are initialized, codes3[0][1] [...]*/},{}/*Changed channels codes3[1] [...]*/}; cout << "codes3[0][0][1] = " << codes3[0][0][1] << endl; // 2 elements in the first row and the second column of the first channel cout << "codes3[0][1][0] = " << codes3[0][1][0] << endl; // 4 elements in the first channel, the second row and the first column // Sets the value of the array codes1[0] = 123; codes2[0][0] = 445; codes3[0][0][2] = 234;
29.2 multi level pointer
int codes1[10] = {1,2,3}; // One dimensional array int codes2[5][10] = {{1,2},{4,5},{},{},{1,2,3,4,5,6,7,8,9,200}}; int codes3[5][10][100] = {{{1,2},{4,5}},{}}; int *p1 = codes1; // The single pointer p1 stores the address, and the memory space pointed to by the address stores the int value // int **pp2 = codes2; // report errors int **pp2 = (int**)codes2;//Double pointer, pp2 stores the address, and the memory pointed to by the address stores the pointer (also the address) // cout << pp2[2][3] << endl; // report errors int *pp1 = new int; // no problem // int **pp2 = new int[10][10] / * an error is reported. This sentence only assigns a value to pp2 and does not create a new memory space for the contents of pp2*/ int **ppp2 = (int**)new int[10][10]; // **ppp2 = 3; // report errors int* xyz[10]; // The elements in the array are pointers to int values // *xyz[0] = 3; // If an error is reported, write a value to the memory space pointed to by the first pointer of XYZ array int* xyz[10]; xyz[0] = new int; // To allocate memory space where the first pointer points *xyz[0] = 3; // correct int **pppp2 = new int*[10]; // Normally, allocate memory space with a length of 10 int * for the secondary pointer for(int i =0; i < 10;i++) { *(pppp2+i) = new int[10]; // Allocate memory space with a length of 10 ints for each element (int *) } **pppp2 = 203; // correct **(pppp2 + 1) = 100; //Add one to the secondary pointer, indicating that the line is added one, which is moved down one line; How to get 100 by array? cout << "**(pppp2 + 1) = " << pppp2[0][1] << endl; // 0, not 100 cout << "**(pppp2 + 1) = " << pppp2[1][0] << endl; // 100
30.vector template class foundation
#include <iostream> #Include < vector > / / declare library functions using namespace std; int main(int argc, const char * argv[]) { // The vector template class can be regarded as a dynamic array // Can be used as an array or stack vector<int> values; // Elements in vector can only store int type values, and values is a vector type variable // Add three elements dynamically values.push_back(20); // first values.push_back(40); // the second values.push_back(60); // Third for(int n:values) // Enumerate all elements in value { cout << n << endl; // 20 40 60 } // Deletes the specified element // values.pop_back(); // Out of the stack, delete the last element, and 60 is gone //values.erase(values.begin()); // Delete the first element, 20 is gone values.erase(values.begin() + 1); // Delete the second element, 40 is gone // Get vector size long size = values.size(); cout << "values size = " << size << endl; // 2 elements, not 2 bytes for(long i = size - 1; i>=0;i--) // Enumerate the values in the vector variable in reverse order by array { cout << values[i] << endl; // 60 20 } cout << values.at(0) << endl; // 20. Utilization at index the elements in the array return 0; }
31. Array template
The difference between array and array template
- Array and array template are different in late initialization
- Variables are allowed for the size of the array, but variables are not allowed for the size of the array template, but constants or numeric values can be used
- Arrays can be used as pointers to some extent, but array templates cannot
- The array template makes it easier to get the size of the array (with. size())
- Assigning an array to a pointer is a reference copy, and the assignment between array templates is a value copy
Note: neither the array nor the array template should exceed the maximum index
#include <iostream> #Include < array > / / declaration using namespace std; int main(int argc, const char * argv[]) { array<string, 5> productNames = {"iPhone6", "iPhone6 Plus"}; array<int,3> codes; codes = {200,300,400}; // Array templates can be defined first and then initialized as a whole int codes1[3]; //If an ordinary array is not initialized at the time of definition, it can only be initialized for a single element, not the whole codes1[0] = 200; // no problem // codes1 = {1,2,3}; // syntax error int n = 100; // variable int codes1[n]; // Variables can be used to define array sizes const int size = 3; // constant // int size = 3; // An error will be reported at the array template array<int,size> codes; codes = {200,300,400}; cout << "productNames[0] = " << productNames[0] << endl; // The index method of array template is the same as that of array if(productNames[4] == "") { cout << "productNames[4]uninitialized" << endl; } cout << "codes[2] = " << codes[2] << endl; int abc[3] = {1,2,3}; cout << "abc[0] = " << *abc << endl; /* 1 ,Arrays and pointers are common to some extent. When you value the array name, you will get the value of the first element */ cout << "productNames size is " << productNames.size() << endl; /* Print the size of the array template (number of elements) */ cout << "abc size is " << sizeof(abc)/sizeof(int) << endl; /* Print the size of the array (number of elements) */ //abc[5] = 3; // No error is reported, and the C + + compiler does not detect boundaries // productNames[10] = 4; // No error is reported, but the output may be garbled // cout << "productNames[10] = " << productNames[10] << endl; // The output is garbled // Enumerate elements in an array template for(int i = 0;i < 2;i++) { cout << productNames[i] << endl; // iPhone6 iPhone6 Plus } for(int value:codes) { cout << value << endl; // 200 300 400 } // Assignment of array template array<int , 3> codes1; codes1 = codes; // This is a value assignment, not a reference assignment, so changing codes1 will not affect codes codes1[0] = 123; cout << "codes1[0] = " << codes1[0] << endl; // 123 cout << "codes[0] = " << codes[0] << endl; // 200 int codes2[]{1,2,3}; // int codes3[] = codes2; // Syntax does not allow direct assignment between arrays int *pCodes = codes2; // A pointer can be used to copy a reference pCodes[0] = 321; // The value of codes2 will also change cout << "codes2[0] = " << codes2[0] << endl; // 321 return 0; }