C++学习笔记——指针

发布时间:2024年01月22日

1,指针的基本概念

指针的作用:可以通过指针间接访问内存

  • 内存的编号是从0开始记录的,一般用十六进制数字表示
  • 可以利用指针变量保存地址

上图中的p就是a变量的指针,也可以记作*a

2,指针变量的定义和使用

指针变量定义语法:数据类型*变量名;

int main(){
	//1,指针的定义 
	int a=10;
	int *p; 
	p=&a;//指针指向变量a的地址 
	cout<<"a的地址为 "<<&a<<endl;//打印数据a的地址:0x6ffe14
	cout<<"指针p为 "<<p<<endl;//打印指针变量p:0x6ffe14
	//2, 使用指针
	//可以通过解引用的方式来找到指针指向的内存 
	//指针前加*代表解引用,找到指针指向的内存中的数据
	*p=1000;
	cout<<"a= "<<a<<endl;
	cout<<"*p= "<<*p<<endl; 
}

*p——解引用的含义,可以通过指针来保存一个地址:?

3,指针所占内存空间

指针与数组一样,也是一种数据结构,既然是一种数据结构,那么所占的内存空间是多少呢?

  • 在32位操作系统下,指针是占4个字节空间大小,不管是什么数据类型。
  • ?在64位操作系统下,指针是占8个字节空间大小。(博主这里的os用的是64位的)

4,空指针和野指针

空指针:指针变量指向内存中编号为0的空间

用途:初始化指针变量

注意:空指针指向的内存是不可以访问的

int main(){
    //指针变量p指向内存地址编号为0的空间
    int *p=NUll;
    //访问空指针报错
    //内存编号为0~255为系统所占内存,不允许用户访问
    cout<<*p<<endl;
}

野指针:指针变量指向非法的内存空间

int main(){
    //指针变量p指向内存地址编号为0x1100的空间
    int *p=(int *)0x1100;
    //访问野指针报错
    cout<<*p<<endl;
    
}

(int *)0x1100的作用在于将后面的0x1100十六进制数强制转换为内存地址。?

5,const修饰指针

const——n.常数;恒量????????adj.恒定的;不变的

假设有以下情景,a,b,p的值如下


const修饰指针有三种情况:

1,const修饰指针——常量指针

特点:指针的指向可以修改,但指针指向的值不可以修改

const int *p=&a;
*p=20;//错误,指针指向的值不可以修改
p=&b//正确,指针的指向可以改

?(红框为不允许)

2,const修饰常量——指针常量

特点:指针的指向不可以改,指针指向的值可以改,与常量指针正好相反。?

int * const p=&a;
*p=20;//正确,指向的值可以改
p=&b;//错误,指针指向不可以改

?

(红线为不允许)

3,const既修饰指针,又修饰常量

特点,指针的指向和指针指向的值都不可以改

const int * const p=&a;
*p=20;//错误
p=&b;//正确

?(红线红框均不可改)

6,指针和数组

作用:利用指针访问数组中元素

#include<bits/stdc++.h>
using namespace std;
int main(){
	int arr[]={1,2,3,4,5,6,7,8,9,10};
	int *p=arr;
	for(int i=0;i<10;i++){
		cout<<*p<<endl;
		p++;//因为p是整形指针,p++的时候地址就会移动四个字节,到数组的下一个数据。
	}
}

输出结果:?

7,指针和函数

作用:利用指针做函数参数,可以修改实参的值
?

#include<bits/stdc++.h>
using namespace std;
void swap1(int a,int b){
	int temp=a;
	a=b;
	b=temp;
}
//地址传递
void swap2(int *p1,int *p2){
	int temp=*p1;
	*p1=*p2;
	*p2=temp;
} 
int main(){
	//指针和函数
	//1,值传递
	int a=10;
	int b=20;
	//swap1(a,b);a=20,b=10
	//2,地址传递
	//如果是地址传递,可以修饰实参
	swap2(&a,&b);
	cout<<"a= "<<a<<"b= "<<b<<endl; //a=20,b=10
}

?

?a,b更换前后,内存空间的内容变化。

8,指针,数组,函数

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

例如数组:int arr[10]={4,3,6,9,1,2,10,8,7,5}

#include<bits/stdc++.h>
using namespace std;
void swap(int *arr,int len){//冒泡排序
	for(int i=0;i<len-1;i++){
		for(int j=0;j<len-i-1;j++){
			if(arr[j]>arr[j+1]){
				int temp=arr[j];
				arr[j]=arr[j+1];
				arr[j+1]=temp;
			}
		}
	}
} 
void printarr(int *arr,int len){
	for(int i=0;i<len;i++){
		cout<<arr[i]<<endl;
	}
}
int main(){
	int arr[10]={4,3,6,9,1,2,10,8,7,5};
	int len=10;
	swap(arr,len);
	printarr(arr,len);
}

此案例的重点在于让我们学会:

  • 将数组传进函数中,即是把数组首地址传入即可
  • 冒泡排序熟练的运用
  • 为使函数体更加灵活,在数组长度方面选择一个形参,而非固定长度
文章来源:https://blog.csdn.net/qq_52788787/article/details/135732478
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。