Day 05 C++ 入门 之 指针

Day 05 C++ 入门之指针

一、指针的基本概念

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

内存是有编号的(每一个空间都有属于自己的编号),内存编号是从0开始记录的,一般用十六进制数字表示;可以利用指针变量保存地址。

简单来说,指针就是一个地址,指针是一个变量,这个变量保存的是一个空间(地址)的编号

1.1 指针变量的定义和使用

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

c++ 复制代码
int a = 7;
// 定义一个指针
int* p;
// 让指针记录变量a的地址
p = &a;// 建立关系
cout << "a的地址为:" << &a <<endl;
cout << "a的地址为:" << p <<endl;// 二者输出的值相同

p指向变量a所存在的空间

1.2 指针的使用

解引用使用指针,表示指针p所指向的内存空间的数值

c++ 复制代码
//解引用来使用 *指针变量名
*p = 8;//将p所指向的内存的变量进行了赋值为8,即a变成了8
1.3 指针所占的内存空间:

指针也是一种数据类型,不管什么类型,都占内存空间为4个字节(32位(x86)操作系统下),64位(x64)操作系统下占8个字节。

c++ 复制代码
int* p;
sizeof(p);
sizeof(int*);
sizeof(char*);
sizeof(double*);
二、空指针

指针变量指向内存中编号为0的空间;被用于初始化指针变量;空指针(指向的内存)不可以访问

c++ 复制代码
int* p;
int* p = NULL;//空指针

空指针不可以访问,不可以解引用赋值。0~255之间的内存编号是系统占用的,因此不可以访问

三、野指针

指针变量指向非法的内存空间,不指向已有变量,也不指向空指针

c++ 复制代码
int* p = (int*)0x1100;// 一个数,强制转为地址+(int*)

这个地址空间我们没有去申请,就去使用他,这是不行的,是一个常见的一种错误,要尽量避免出现野指针

空指针和野指针都不是我们申请的空间,不要随意的去使用。

四、const修饰指针

const修饰指针有三种情况:

1. const修饰指针----常量指针

这个指针的指向可以改,但是指针指向的值不可以改。可以改指向,即原来指向a,现在进行更改,指向b、c、d等;但是不能更改指针指向的值,即指针指向的值不可以被更改,现在指向a,a的值不可以被修改。

2. const修饰常量----指针常量

指针指向不可以修改,但是指针指向的值可以被修改

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

指针的指向和指向的值都不可以更改。即认定了,只能是它,不接受更改

c++ 复制代码
int a =7;
int b = 8;
int* p = &a;
//1. const修饰指针----常量指针
const int* p = &a;
p = &b;//正确,可以修改指向
*p =6;//错误,不可以修改指向的值
//2. const修饰常量----指针常量
int* const p = &a;
*p = 6;//正确
p = &b; //错误
//3. const既修饰指针,又修饰常量
const int* const p = &a;

注:常量指针,可以修改指针指向,(可以换男朋友,但不可以换底线(值));指针常量,可以修改值,(不换男朋友,一直换底线!!!)

只要被const修饰的就不可以改,const后面的就不可以改

五、指针和数组

利用指针访问数组中的元素。创建指针指向数组名(数组的数组名 = 数组首地址)即可。解引用就可以访问一个数组的首元素。

c++ 复制代码
int A[7]={1,2,3,4,5,6,7};
int* p = A;
cout << "第一个元素是"  << *p << endl;
for(int i =0;i<7;i++)
{
    cout << "第" << i+1 <<" 个元素是"  << *p << endl;
    p++;//是一个整型指针,所以+1就是往后移动一个整型数据所占空间的大小
}

指针指向数组之后,指针+1=向后移动一个数组元素的空间大小,即指向下一个元素

六、指针和函数

利用指针作函数的参数,可以修改实参的值。指针作为参数传递,传的是参数的地址

c++ 复制代码
//值传递
void swap1(int num1,int num2)
{
    int temp = num1;
    num1 = num2;
    num2 = temp;   
}

//址传递
void swap2(int* p,int* q)
{
    int temp = *p;
    *p = *q;
    *q = temp;   
}

int main()
{
    
    int a = 7;
    int b = 6;
    swap1(a, b);
    cout << "现在a、b的值为" << a << " 、" << b << endl;//7、6
    swap2(&a, &b);
    cout << "现在a、b的值为" << a << " 、" << b << endl;//6、7
	system("pause");
	return 0;

}

前面函数讲的是值传递,值传递是在另一片空间新开几个空间进行赋值,实参和形参是两个不同的空间。

这里讲的是址传递,传的是参数的地址,而内存空间的地址是没有重复的完全一样的编号的,所以这样实参和形参指向的是同一个地址,所以形参的改变会影响实参的改变,也就是说,形参的改变就是实参的改变。

七、指针配合数组和函数的例子

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

{4,3,6,9,1,2,10,8,7,5}

c++ 复制代码
//冒泡排序函数
//传数组,传的是数组的首地址。
void bubbleSort(int* A, int n)
{
    for (int i = 0; i < n - 1; i++)
    {
        for (int j = 0; j < n - i - 1; j++)
        {
            if (A[j] > A[j+1])
            {
                int temp = A[j];
                A[j] = A[j + 1];
                A[j+1] = temp;
            }
        }
    }
}
int main()
{
    int A[10] = {4,3,6,9,1,2,10,8,7,5};
    int* p = A;
    bubbleSort(p,10);
    for(int i=0;i<10;i++){
        cout << A[i] << endl;
    }
	system("pause");
	return 0;

}
相关推荐
Scott9999HH37 分钟前
【IIoT流量实战】蒸汽管道阀门全关却仍有流量?用 Python 实现涡街信号 FFT 频谱分析与温压全补偿积算网关,深度拆解靠谱的涡街流量计厂家硬核技术标准
开发语言·python
2401_841495641 小时前
【操作系统】进程同步与互斥实验报告
c++·算法·操作系统·进程·并发·同步·互斥
fqbqrr2 小时前
2607C++,soui与安卓
c++·soui
码智社2 小时前
AES加密原理详解及Java实现加解密实战
java·开发语言
AI云海2 小时前
python 列表、元组、集合和字典
开发语言·python
克里斯蒂亚诺更新2 小时前
ruoyi角色权限的对应关系
笔记
萧瑟余晖3 小时前
JDK 26 新特性详解
java·开发语言
马优晨3 小时前
Freemarker 完整讲解(后端 Java 模板引擎)
java·开发语言·freemarker·freemarker 完整讲解·freemarker模板引擎
a1117765 小时前
2FA 验证码生成器(github登录验证 app)
笔记·学习
fqbqrr5 小时前
2607C++,使用微软detours勾挂工具
c++