[C/C++]: Pointer

1 The difference between pointers and constants:

The difference between pointer constants and constant pointers: https://www.cnblogs.com/lizhenghn/p/3630405.html

1. Null pointer

When the variable is declared, if there is no exact address to assign, it is a good programming practice to assign a NULL value to the pointer variable. A pointer assigned a NULL value is called a null pointer.

The NULL pointer is a constant defined in the standard library with the value zero. Please see the procedure below:

example

#include <iostream>

using namespace std;

int main ()
{
    
    
   int  *ptr = NULL;

   cout << "ptr 的值是 " << ptr ;
 
   return 0;
}

When the above code is compiled and executed, it produces the following result:

The value of ptr is 0
On most operating systems, programs are not allowed to access memory at address 0, because this memory is reserved by the operating system. However, memory address 0 has special significance, indicating that the pointer does not point to an accessible memory location. But by convention, if a pointer contains a null value (the value of zero), it is assumed not to point to anything.

To check for a null pointer, you can use an if statement, as follows:

if(ptr) /* completes if ptr is non-null /
if(!ptr) /
completes if ptr is null */
So if all unused pointers are given null values ​​while avoiding null pointers, just prevents misuse of an uninitialized pointer. Many times, uninitialized variables hold some garbage value, making the program difficult to debug.

2. Array of pointers

Declares ptr as an array consisting of MAX integer pointers. Therefore, each element in ptr is a pointer to an int value. The following example uses three integers, which will be stored in an array of pointers, as follows:

example

#include <iostream>
 
using namespace std;
const int MAX = 3;
 
int main ()
{
    
    
   int  var[MAX] = {
    
    10, 100, 200};
   int *ptr[MAX];
 
   for (int i = 0; i < MAX; i++)
   {
    
    
      ptr[i] = &var[i]; // 赋值为整数的地址
   }
   for (int i = 0; i < MAX; i++)
   {
    
    
      cout << "Value of var[" << i << "] = ";
      cout << *ptr[i] << endl;
   }
   return 0;
}

When the above code is compiled and executed, it produces the following result:

Value of var[0] = 10
Value of var[1] = 100
Value of var[2] = 200

3. Pointer to Pointer

A pointer to a pointer is a form of multi-level indirection, or a chain of pointers.
A pointer to a pointer is to store the address of a pointer in another pointer.
Usually, a pointer contains the address of a variable. When we define a pointer to pointer, the first pointer contains the address of the second pointer, which points to the location containing the actual value.
insert image description here

#include <iostream>
 
using namespace std;
 
int main ()
{
    
    
    int  var;
    int  *ptr;
    int  **pptr;
 
    var = 3000;
 
    // 获取 var 的地址
    ptr = &var;
 
    // 使用运算符 & 获取 ptr 的地址
    pptr = &ptr;
 
    // 使用 pptr 获取值
    cout << "var 值为 :" << var << endl;
    cout << "*ptr 值为:" << *ptr << endl;
    cout << "**pptr 值为:" << **pptr << endl;
 
    return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:

var 值为 :3000
*ptr 值为:3000
**pptr 值为:3000

4 Pass pointers to functions

C++ allows you to pass pointers to functions by simply declaring the function parameters as pointer types.

#include <iostream>
using namespace std;
 
// 函数声明
double getAverage(int *arr, int size);
 
int main ()
{
    
    
   // 带有 5 个元素的整型数组
   int balance[5] = {
    
    1000, 2, 3, 17, 50};
   double avg;
 
   // 传递一个指向数组的指针作为参数
   avg = getAverage( balance, 5 ) ;
 
   // 输出返回值
   cout << "Average value is: " << avg << endl; 
    
   return 0;
}
 
double getAverage(int *arr, int size)
{
    
    
  int    i, sum = 0;       
  double avg;          
 
  for (i = 0; i < size; ++i)
  {
    
    
    sum += arr[i];
   }
 
  avg = double(sum) / size;
 
  return avg;
}

5. The function returns a pointer

A function returning a pointer must be declared as follows:

int * myFunction()
{
    
    
.
.
.
}

In addition, C++ does not support returning the address of a local variable outside a function, unless the local variable is defined as a static variable.

//生成 10 个随机数,并使用表示指针的数组名(即第一个数组元素的地址)来返回它们
#include <iostream>
#include <ctime>
#include <cstdlib>
 
using namespace std;
 
// 要生成和返回随机数的函数
int * getRandom( )
{
    
    
  static int  r[10];
 
  // 设置种子
  srand( (unsigned)time( NULL ) );
  for (int i = 0; i < 10; ++i)
  {
    
    
    r[i] = rand();
    cout << r[i] << endl;
  }
 
  return r;
}
 
// 要调用上面定义函数的主函数
int main ()
{
    
    
   // 一个指向整数的指针
   int *p;
 
   p = getRandom();
   for ( int i = 0; i < 10; i++ )
   {
    
    
       cout << "*(p + " << i << ") : ";
       cout << *(p + i) << endl;
   }
 
   return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:

624723190
1468735695
807113585
976495677
613357504
1377296355
1530315259
1778906708
1820354158
667126415
*(p + 0) : 624723190
*(p + 1) : 1468735695
*(p + 2) : 807113585
*(p + 3) : 976495677
*(p + 4) : 613357504
*(p + 5) : 1377296355
*(p + 6) : 1530315259
*(p + 7) : 1778906708
*(p + 8) : 1820354158
*(p + 9) : 667126415

2. The difference between & and *

The pointer is the address of the variable
&: Get the address of the variable
Unary operator
: Return the value of the variable at the address specified by the operand
*
Simple example analysis:

int main()
{
    
    
	int a = 3;
	int *b = &a;
	cout << "a:" << a << endl;
	cout << "b:" << b << endl;
	*b = 10;
	cout << "&a:" << &a << endl;
	cout << "b:" << b << endl;
	cout << "a=" << &a << endl;
	system("pause");
}

结果:
a:3
b:00EFFE28
&a:00EFFE28
b:00EFFE28
a=10

**b是a的指针,指向a的地址。(也就是a与b相连,只要修改*b的值,a的值也跟着改动)**

3. Classes and pointers

kind

https://blog.csdn.net/keneyr/article/details/89364275
https://www.jianshu.com/p/a75b267325c2

void pointer

The void pointer has no type. Any pointer can be assigned to the void pointer without conversion, only the address is needed but not the length, and the pointer to the object cannot be judged. void *vp; int *p; vp=p;

However, when the void pointer is assigned to other types of pointers, type conversion is required. The purpose of type conversion is to obtain the size of the pointed variable/object type p=(type )vp;

The void pointer cannot be dereferenced *vp//error because the void pointer only knows the starting address of the variable/object, but does not know the size of the variable/object (accounting for a few bytes), so it cannot be referenced correctly.

Void pointers cannot participate in pointer arithmetic unless converted (type*) vp++; //vp==vp+sizeof(type)

The difference between void * and void in the return value of the function is:
in the return value of the function, void does not have any return value, and void * is a pointer that returns a value of any type.

4 Returning pointers and arrays from functions

function return pointer by function

#include <iostream>

using namespace std;

void splitfloat(int *x,int *y)//形参x,y为指针
{
    
    

	int x1 = 1;
	int y1 = 100;

	*x = y1 + x1;
	*y = y1 - x1;
}


int main()
{
    
    
	int n=0, f=0;
	splitfloat(&n, &f);  //变量地址作为实参
	cout << "n:" << n << endl;
	cout << "f:" << f << endl;

Function returns pointer and array by function
test.h file

#ifndef TEST_H_
#define TEST_H_

int a[4][2];
int x0;

#endif

.cpp file

#include <iostream>
#include "test.h"

using namespace std;

void splitfloat(int *x)       //形参x为指针
{
    
    
	
	int x1 = 1;
	int y1 = 100;
	for (int m = 0; m < 4; m++)
	{
    
    
		for (int n = 0; n < 2; n++)
		{
    
    

			a[m][n] = m+x1;
			cout << "a[" << m << "]" << "[" << n << "]:" << a[m][n] << endl;
			x1 += 1;
		}
	}
	
	//for (int i = 0; i < 4; i++)
	//{
    
    
	//	x0 = x1 + i;
	//	
	//}
	//	//*x = x1 + i;
	//	
	//	*x = x0;
		
}



int main()
{
    
    
	int n=0,f=0;

	//int a[4][2] = {0};
	

	splitfloat(&n);  //变量地址作为实参
	
	cout << "a[0][0]:" << a[0][0] << endl;
	cout << "a[0][1]:" << a[0][1] << endl;
	cout << "a[1][0]:" << a[1][0] << endl;
	cout << "a[1][1]:" << a[1][1] << endl;
	cout << "a[2][0]:" << a[2][0] << endl;
	cout << "a[2][1]:" << a[2][1] << endl;
	cout << "a[3][0]:" << a[3][0] << endl;
	cout << "a[3][1]:" << a[3][1] << endl;
	/*for (int j = 0; j < 4; j++)
	{
		for (int k = 0; k < 2; k++)
		{
			cout << "a[" << j << "]" << "[" << k << "]:" << a[j][k] << endl;
		}
	}*/
	//cout << "f:" << f << endl;
	/*cout << "a[0]:" << a[0] << endl;
	cout << "a[1]:" << a[1] << endl;
	cout << "a[2]:" << a[2] << endl;
	cout << "a[3]:" << a[3] << endl;*/
}

5. Dynamic memory allocation of pointers

Dynamic memory allocation for pointer arrays:


#include <iostream>

using namespace std;

int main()
{
    
    
  // 开始为二维的动态数组设置内存容量
	
	int **test2 = new int *[5];
	for (int j = 0; j < 5; j++)
	{
    
    
		test2[j] = new int [3];
	}

	for (int i = 0; i < 5; i++)
	{
    
    
		for (int k = 0; k < 3; k++)
		{
    
    
			test2[i][k] = i + k;
		}
	}

	for (int i = 0; i < 5; i++)
	{
    
    
		for (int k = 0; k < 3; k++)
		{
    
    
			cout << "test2[i][k]" << test2[i][k] << "\n";
		}
	}

	// 释放内存
	for (int k = 0; k < 3; k++)
	{
    
    
		delete[] test2[k];
	}
	delete[] test2;

	return 0;
}



Dynamic memory allocation of class pointers:

#include <iostream>
using namespace std;

class Box
{
    
    
public:
	Box() {
    
    
		cout << "调用构造函数!" << endl;
	}
	int test() {
    
    
		cout << "调用test()函数!" << endl;
		return 0;
	}
	~Box() {
    
    
		cout << "调用析构函数!" << endl;
	}
};

int main()
{
    
    
	cout << "1调用析构函数!" << endl;
	Box *myBoxArray = new Box;
	cout << "2调用析构函数!" << endl;
	int result = myBoxArray->test();
	cout << "3调用析构函数!" << endl;
	delete myBoxArray; // 删除数组
	cout << "4调用析构函数!" << endl;
	return 0;
}

Guess you like

Origin blog.csdn.net/weixin_44322778/article/details/123221681