• 【C++】C++基础知识(七)---指针


    1. 指针的定义与使用

    指针的作用:
    ------通过指针可以直接的访问变量的内存,内存编号一般是从0开始记录的,一般用16进制数来表示,可以利用指针变量保存地址。

    指针的定义语法:
    ------数据类型 * 指针变量名
    指针是一个变量,其值为另一个变量的地址,即内存位置的直接地址。

    指针的使用:
    ------可以通过解引用的方式找到指针指向内存中的数据,指针前加 * 表示:找到指针指向的内存中数据。

    注意:
    1、我们知道每一个变量都有一个内存位置,每一个内存位置都定义了可使用 & 运算符访问的地址,它表示了变量在内存中的一个地址;指针变量指向的就是变量的内存地址。
    2、通过在指针变量前加 * 一元操作符来返回位于操作数所指定地址的变量的值。*指针变量可以访问指针变量指向的内存地址中所对应的值。

    • 代码演示
    #include 
    using namespace std;
    
    int main() {
    
    	// 1、指针的定义
    	int a = 1314;
    	int * p = &a;
    
    	cout << "变量a的地址为:" << &a << endl;
    	cout << "指针p为:" << p << endl;
    
    	// 2、指针的使用
    	*p = 2022;
    	cout << "a = " << a << endl;
    	cout << "*p = " << *p << endl;
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 输出结果
      在这里插入图片描述

    2. 指针的内存

    指针也是一种数据类型,它在32位操作系统中占用4个字节,在64位操作系统中占用8个字节

    • 代码演示
    #include 
    using namespace std;
    
    int main() {
    
    	cout << "sizeof(int *) = " << sizeof(int *) << endl; //整型指针
    	cout << "sizeof(float *) = " << sizeof(float *) << endl; //单精度浮点型指针
    	cout << "sizeof(double *) = " << sizeof(double *) << endl; //双精度浮点型指针
    	cout << "sizeof(char *) = " << sizeof(char *) << endl; //字符型指针
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 输出结果
      32位操作系统中(visual studio2022中解决方案平台为x86):
      在这里插入图片描述
      64位操作系统中(visual studio2022中解决方案平台为x64):
      在这里插入图片描述

    3. 空指针和野指针

    空指针
    ------指针变量指向内存编号为0的空间,内存编号0-255为系统内存,不允许用户访问
    用途:
    ------用于初始化指针变量
    注意:
    ------空指针指向的内存变量是不可以访问的,否则会报错

    野指针
    ------指针变量指向非法访问的内存空间
    注意:
    ------空指针与野指针都不是我们申请访问的内存空间,因此不要访问空指针和野指针指向内存中的数据。

    • 代码演示
    #include 
    using namespace std;
    
    int main() {
    
    	//空指针
    	int* p = NULL;
    	
    	//访问空指针会报错
    	cout << *p << endl;
    
    	//野指针
    	int* p1 = (int*)0x1100;
    	//访问野指针会报错
    	cout << *p1 << endl;
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 输出结果
      访问空指针时:
      在这里插入图片描述
      访问野指针时:
      在这里插入图片描述

    4. const修饰指针

    const修饰指针有三种情况:
    ------1、const修饰指针(常量指针)
    -----------指针的指向可以改,但是指针指向的值不能修改
    ------2、const修饰常量(指针常量)
    -----------指针的指向不能修改,但是指针指向的值可以修改
    ------3、const即修饰指针又修饰常量
    -----------指针的指向和指针指向的值均不能修改

    注意:
    ------如何看const修饰的是指针还是常量,只需要看const后面紧跟着的是指针还是常量,如果是指针,则为常量指针;如果是常量,则为指针常量。

    • 代码演示
    #include 
    using namespace std;
    
    int main() {
    
    	int a = 2022;
    	int b = 1108;
    	// 1、const修饰指针 ---常量指针
    	// 指针的指向可以改,但是指针的指向的值不能改
    	const int* p1 = &a;
    	p1 = &b;
    	//*p1 = 2050; //报错,指针指向的值不能修改
    
    	// 2、const修饰常量 ---指针常量
    	// 指针的指向不能修改,但是指针指向的值可以修改
    	int* const p2 = &a;
    	//p2 = &b; //报错,指针的指向不能改
    	*p2 = 2050;
    
    	// 3、const即修饰指针又修饰常量
    	// 指针的指向和值均不能修改
    	const int* const p3 = &a;
    	//p3 = &b; //报错
    	//*p3 = 2050; //报错
    
    	system("pause");
    	return 0;
    }
    
    • 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
    • 输出结果
      const修饰指针(常量指针)修改指针指向的值时报错:
      在这里插入图片描述
      const修饰常量(指针常量)修改指针的指向时报错:
      在这里插入图片描述
      const即修饰指针又修饰常量时修改指针的指向或者修改指向的值时均报错:
      在这里插入图片描述

    5. 指针与数组

    指针与数组是有一定联系的,我们可以利用指针访问数组中的元素。

    • 代码演示
    #include 
    using namespace std;
    
    int main() {
    
    	int arr[10] = {1,9,9,5,4,8,6,0,9,3};
    	int* p = arr; //数组名就是这个数组的首地址
    	for (int i = 0; i < 10; i++)
    	{
    		cout << *p << " "; //*p解引用对应指针指向的值
    		p++; //p代表指针指向的地址
    	}
    	cout << endl;
    
    	system("pause");
    	return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 输出结果
      在这里插入图片描述

    6. 指针与函数

    指针可以用作函数的形参,用来修改实参的值
    1、值传递
    -----不能用来修饰实参
    2、地址传递
    -----可以用来修饰实参
    原因如下图所示:
    在这里插入图片描述

    • 代码演示
    #include 
    using namespace std;
    
    void swap1(int num1,int num2)
    {
    	int temp = num1;
    	num1 = num2;
    	num2 = temp;
    	cout << "num1 = " << num1 << endl;
    	cout << "num2 = " << num2 << endl;
    }
    
    void swap2(int *p1,int *p2)
    {
    	int temp = *p1;
    	*p1 = *p2;
    	*p2 = temp;
    	cout << "*p1 = " << *p1 << endl;
    	cout << "*p2 = " << *p2 << endl;
    }
    
    int main() {
    
    	// 1、值传递
    	int a = 2022;
    	int b = 1108;
    	int c = 2022;
    	int d = 1108;
    	swap1(a, b);
    	cout << "swap1 a = " << a << endl;
    	cout << "swap1 b = " << b << endl;
    
    	// 2、地址传递
    	swap2(&c, &d);
    	cout << "swap2 c = " << c << endl;
    	cout << "swap2 d = " << d << endl;
    
    	system("pause");
    	return 0;
    }
    
    • 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
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 输出结果
      在这里插入图片描述

    7. 指针用于数组和函数的案例

    • 案例描述

    封装一个函数,利用冒泡排序,实现对整个数组的升序排列

    • 思路分析

    1、利用指针来访问数组中的元素;
    2、利用指针作函数的形参;
    3、封装一个bubblesort()函数,实现数组中元素的升序排列;

    • 代码实现
    #include 
    using namespace std;
    
    // 函数功能:实现数组中元素的升序排列
    // 函数参数:(参数1:数组元素首地址;参数2:数组的长度。)
    // 传入数组长度这个参数是为了便于代码的管理和修改
    void bubblesort(int* arr, int length)
    {
    	for (int i = 0; i < length - 1; i++ )
    	{
    		for (int j = 0; j < length - i - 1; j++)
    		{
    			if (arr[j] > arr[j + 1])
    			{
    				int temp = arr[j];
    				arr[j] = arr[j + 1];
    				arr[j + 1] = temp;
    			}
    		}
    	}
    }
    
    int main() {
    
    	// 1、定义一个整型数组
    	int arr[10] = {6,8,0,2,3,5,1,7,9,4};
    	int len = sizeof(arr) / sizeof(arr[0]);
    
    	// 2、封装一个升序排列函数
    	bubblesort(arr,len);
    
    	// 3、对升序排列后的结果进行打印
    	for (int i = 0; i < 10; i++)
    	{
    		cout << arr[i] << " ";
    	}
    	cout << endl;
    
    	system("pause");
    	return 0;
    }
    
    • 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
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 输出结果
      在这里插入图片描述
  • 相关阅读:
    将 ChatGLM2-6B 部署成 OpenAI API 服务
    常见的排序算法的时间复杂度
    Vue详解及综合案例
    Java 面试题 (二) -------- Java 集合相关
    165 pbi-utils 使用文档
    第五章 MyBais插件
    【java】ArrayList和LInkedList的区别
    [附源码]计算机毕业设计springboot云南美食管理系统
    社区点赞业务缓存设计优化探索
    Docker安装pgAdmin4
  • 原文地址:https://blog.csdn.net/qq_43723025/article/details/127898465