文章目录
- 前言
- 一、指针的定义和使用
- 1.1、指针定义
- 1.2、指针使用
- 二、指针占用的内存空间
- 三、空指针和野指针
- 3.1.空指针
- 3.2 野指针
- 四、const修饰指针
- 4.1 常量指针
- 4.2 指针常量
- 4.3 const既修饰指针也修饰常量
- 五、指针,数组,函数混用案例
- 5.1 指针和数组混用
- 5.2 指针和函数混用
- 5.3 指针,数组,函数混用
前言
本篇笔记是基于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;
}