【C++】指针的基础知识 | 学习笔记


前言

本篇笔记是基于B站课程:C++视频教程
跟着视频我也相当于把代码又敲了一遍

一、指针的定义和使用

1.1、指针定义

指针存放的就是一个地址。
在main函数里,定义如下(以变量a的地址为例子):

int a = 10;
int * p; // 定义指针变量p
p = &a; //&a返回的是a的地址,并将其存放到指针p中

也可以一步到位:

int a = 10;
int * p=&a;

总体代码如下:

#include <iostream>
using namespace std;
int main()
{
    
    
	int a = 10;
	int * p=&a; //指针存放的就是地址
	cout << "指针P为"<< p << endl;
	cout << "变量a的地址是"<<&a << endl;
	return 0;
}

结果:
在这里插入图片描述

1.2、指针使用

在指针前加一个“*”,就能使用其“解引用”的功能,找到指针指向的内存,进行操作,如下所示:

*p = 10000;

完整例子如下:

#include <iostream>
using namespace std;
int main()
{
    
    
	int a = 10;
	int * p=&a; //指针存放的就是地址
	cout << "指针P为"<< p << endl;
	cout << "变量a的地址是"<<&a << endl;
	*p = 10000;
	cout << "变量a为" << a << endl;
	cout << "*p为" << *p << endl;
	return 0;
}

在这里插入图片描述
从结果我们可以看到,变量a的值被修改为了10000,这正是*p的功劳。

二、指针占用的内存空间

32位操作系统下,指针内存占用都是4个字节:

#include <iostream>
using namespace std;
int main()
{
    
    
	int a = 10;
	int * p = &a; 
	cout << sizeof(p) << endl;
	cout << sizeof(int *) << endl;
	cout << sizeof(char *) << endl;
	cout << sizeof(float *) << endl;
	return 0;
}

在这里插入图片描述
64位操作系统下,指针内存占用是8字节
在VS2017这里,可以切换32位系统和64位系统:
在这里插入图片描述
64位下的最终结果:
在这里插入图片描述

三、空指针和野指针

3.1.空指针

定义:指针变量指向内存编号为0的空间。
一般来说空指针用作初始化,其指向的内存是不能访问的。

空指针的定义如下:

int * p = NULL

当我们想访问使用它时,会报错:

#include <iostream>
using namespace std;
int main()
{
    
    
	int * p = NULL;
	cout << *p << endl;
	return 0;
}

或者

#include <iostream>
using namespace std;
int main()
{
    
    
	int * p = NULL;
	*p = 10000;
	return 0;
}

在这里插入图片描述
0-255号内存是系统占用的,无法访问。

3.2 野指针

定义:指针变量指向非法的内存空间
代码如下(示例):

#include <iostream>
using namespace std;
int main()
{
    
    
	int * p = (int *)0x1100;
	cout << *p << endl;
	return 0;
}

上面0x1100这块内存,之前是没有定义的,这里就越界了。
在这里插入图片描述


四、const修饰指针

4.1 常量指针

定义方法:

const int * p = &a

指针的指向可以修改,但是指针指向的值不能改:
下面是可行的:

p = &b;

下面是不可行的

*p = 10000;

4.2 指针常量

定义方法:

const int * p = &a

指针的指向不可以修改,但是指针指向的值可以改:
下面是可行的:

*p = 10000;

下面是不可行的

p = &b;

4.3 const既修饰指针也修饰常量

定义方法:

const int * const p = &a

指针的指向不可以修改,指针指向的值也不可以改:
下面是不可行的:

*p = 10000;

下面是不可行的

p = &b;

五、指针,数组,函数混用案例

5.1 指针和数组混用

#include <iostream>
using namespace std;
int main()
{
    
    
	int arr[] = {
    
     1,2,3,4,5 };
	int *p = arr; //arr是数组首地址
	cout << "第一个元素是" << arr[0] << endl;
	cout << "指针访问的第一个元素是" << *p << endl;

	for (int i = 0; i < 5; i++)
	{
    
    
		cout << *p << endl;
		p++;
	}
	return 0;
}

在这里插入图片描述

5.2 指针和函数混用

值传递,地址传递
值传递不会改变实参,而地址传递会改变实参
(1)值传递

#include <iostream>
using namespace std;
void swap1(int a1, int b1)
{
    
    
	int temp = a1;
	a1 = b1;
	b1 = temp;
	cout << "a1是" << a1 << endl;
	cout << "b1是" << b1 << endl;
}

int main()
{
    
    
	int a = 10;
	int b = 20;
	swap1(a, b);
	cout << "a是"<<a << endl;
	cout <<"b是"<< b << endl;
	return 0;
}

在这里插入图片描述
形参改变了,但是实参没有改变
(2)地址传递

#include <iostream>
using namespace std;
void swap2(int * p1, int * p2)
{
    
    
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
	cout << "*p1是" << *p1 << endl;
	cout << "*p2是" << *p2 << endl;
}
int main()
{
    
    
	int c = 100;
	int d = 200;
	swap2(&c, &d);
	cout << "c是" << c << endl;
	cout << "d是" << d << endl;
	return 0;
}

在这里插入图片描述
形参改变了,实参也改变了

5.3 指针,数组,函数混用

下面是一个冒泡排序的例子

#include <iostream>
using namespace std;
void bubblesort(int * arr, int len)
{
    
    
	for (int i = 0; i < len - 1; i++)
	{
    
    
		for(int j =0;j<len-1;j++)
			if (arr[j] > arr[j + 1])
			{
    
    
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
	}
}
void printarray(int *arr, int len)
{
    
    
	for (int i = 0; i < len; i++)
	{
    
    
		cout << arr[i] << endl;
	}
}
int main()
{
    
    
	int arr[5] = {
    
    3,6,9,2,5};
	int len = sizeof(arr) / sizeof(arr[0]);
	bubblesort(arr, len);
	printarray(arr, len);
	return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_46274756/article/details/128470929