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;

}
相关推荐
etsuyou4 小时前
js前端this指向规则
开发语言·前端·javascript
shizhenshide5 小时前
为什么有时候 reCAPTCHA 通过率偏低,常见原因有哪些
开发语言·php·验证码·captcha·recaptcha·ezcaptcha
挂科是不可能出现的5 小时前
最长连续序列
数据结构·c++·算法
mit6.8245 小时前
[Agent可视化] 配置系统 | 实现AI模型切换 | 热重载机制 | fsnotify库(go)
开发语言·人工智能·golang
友友马5 小时前
『 QT 』QT控件属性全解析 (一)
开发语言·前端·qt
小白学大数据6 小时前
实战:Python爬虫如何模拟登录与维持会话状态
开发语言·爬虫·python
一念&6 小时前
每日一个C语言知识:C 结构体
c语言·开发语言
mjhcsp6 小时前
C++ int 类型深度解析:从底层实现到实战应用
c++·int
mtactor6 小时前
投资理财学习笔记
笔记·学习·金融