指针的作用: 可以通过指针间接访问内存,指针也是一种数据类型
指针变量定义语法: 数据类型 * 变量名;
指针的数据类型:取决于指针指向的内存空间,该内存空间存放的是什么类型数据,如果是数组,那么变量指向的是第一个元素,所以还是取决于数组的数据类型是什么
例子:
#include<iostream>
using namespace std;
int main() {
//创建一个变量
int a = 10;
//定义指针,语法:数据类型 * 指针名
int * p;
//让指针p记录a的地址
p = &a;
cout << &a << endl; //0113F8F0
cout << p << endl; //0113F8F0
//解引用,在指针变量前加*,获取指向的内存空间,进行重新赋值
*p = 100;
cout << a << endl; // 100
system("pause");
return 0;
}
指针变量和普通变量的区别
总结1: 我们可以通过 & 符号 获取变量的地址
总结2:利用指针可以记录地址
总结3:对指针变量解引用,可以操作指针指向的内存
#include<iostream>
using namespace std;
int main() {
int * p;
int size = sizeof(p);
cout << size << endl;
system("pause");
return 0;
}
所有指针类型在32位操作系统下是4个字节
所有指针类型在64位操作系统下是8个字节
空指针:指针变量指向内存中编号为0的空间
用途:初始化指针变量
注意:空指针指向的内存是不可以访问的
#include<iostream>
using namespace std;
int main() {
//用于给指针变量初始化
int * p = NULL;
cout << p << endl; //00000000
//空指针是不可以进行解引用使用的
*p = 100; //报错
system("pause");
return 0;
}
野指针:指针变量指向非法的内存空间
#include<iostream>
using namespace std;
int main() {
//用于给指针变量初始化
int * p = (int *)0x1100;
//野指针不可以进行读写,非法
*p = 100; //报错,写入访问权限冲突
system("pause");
return 0;
}
const修饰指针有三种情况
const修饰指针:指针的指向可以进行修改,不可以对指向内存空间的值进行修改
#include<iostream>
using namespace std;
int main() {
int a = 10;
int b = 20;
const int * p = &a;
p = &b; // 指针的指向可以进行修改
*p = 20; // 不可以对指向内存空间的值进行修改
system("pause");
return 0;
}
const修饰常量:指针的指向不可以进行修改,可以对指向内存空间的值进行修改
#include<iostream>
using namespace std;
int main() {
int a = 10;
int b = 20;
int * const p = &a;
p = &b; // 指针的指向不可以进行修改
*p = 20; // 可以对指向内存空间的值进行修改
system("pause");
return 0;
}
指针的指向和指向内存空间的值都不可以进行修改
#include<iostream>
using namespace std;
int main() {
int a = 10;
int b = 20;
const int * const p = &a;
p = &b; // 指针的指向不可以进行修改
*p = 20; // 不可以对指向内存空间的值进行修改
system("pause");
return 0;
}
作用:利用指针访问数组中元素
示例:
#include<iostream>
using namespace std;
#include<string>
int main() {
//定义一个数组
string a[] = { "lucy","tom","lily","james" };
//a其实保存的就是数组的第一个元素的地址
string * p = a;
//解引用,可以获取数组的第一个元素
cout << *p << endl; //lucy
//由于数组是连续的内存空间,而一个指针占用的内存空间是4个字节,所以只需要将p后移四个字节,就指向了下一个元素
p++;
cout << *p << endl; //tom
system("pause");
return 0;
}
#include<iostream>
using namespace std;
#include<string>
int main() {
//定义一个数组
string a[] = { "lucy","tom","lily","james" };
//定义指针
string * p = a;
for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {
cout << *p << endl;
p++;
}
system("pause");
return 0;
}
由于cpp的函数是值传递,所以如果需要引用传递(类似java),那么需要使用指针作为参数
例子,如果不使用地址传递,那么函数是无法改变a和b的值:
#include<iostream>
using namespace std;
void change(int * a,int * b) {
int temp = *b;
*b = *a;
*a = temp;
}
int main() {
int a = 10;
int b = 20;
change(&a, &b);
cout << "a = " << a << endl;
cout << "b = " << b << endl;
system("pause");
return 0;
}
封装一个函数,利用冒泡排序,实现对整型数组的升序排序
int arr[10] = { 4,3,6,9,1,2,10,8,7,5 }
#include<iostream>
using namespace std;
//冒泡升序排序
void mopoSort(int * arr,int length) {
for (int i = 0; i < length - 1; i++) {
for (int j = 0; j < length - 1 - i; j++) {
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
//遍历数组
void toStringArr(int * arr,int length) {
for (int i = 0; i < length; i++) {
cout << arr[i] << endl;
}
}
int main() {
int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
//数组的长度
int length = sizeof(arr) / sizeof(arr[0]);
mopoSort(arr, length);
toStringArr(arr, length);
system("pause");
return 0;
}