C++30天学习打卡(六)
个人博客地址
个人笔记记录而已,需要C++资料的可以在下面留言
看的视频和课件都来自黑马程序员公开课
指针
指针的基本概念
- 作用:可以通过指针间接访问内存
- 注意:
- 内存编号是从0开始记录的,一般用十六进制数字表示
- 可以利用指针变量保存地址
指针变量的定义和使用
-
指针变量定义语法:
数据类型 * 变量名;
-
示例:
#include <iostream> using namespace std; int main() { // 指针的定义 int a = 10; // 定义整型变量a // 指针定义 int* p; // 指针变量赋值 p = &a;//指针指向变量a的地址 cout <<"打印数据a的地址:"<< &a << endl; cout <<"打印指针变量p:"<< p << endl; // 指针的使用 // 通过*操作指针变量指向的内存 cout << "*p = " << *p << endl; *p = 100; cout << "a = " << a << endl; c system("pause"); return 0; }
-
指针变量和普通变量区别:
- 普通变量存放的是数据,指针变量存放的是地址;
- 指针变量可以通过" * "操作符操作指针变量指向的内存空间,这个过程称为解引用;
-
总结:
- 我们可以通过 & 符号 获取变量的地址;
- 利用指针可以记录地址;
- 对指针变量解引用,可以操作指针指向的内存。
指针所占内存空间
-
32位操作系统:4个字节
-
64位操作系统:8个字节
-
示例:
#include <iostream> using namespace std; int main() { int a = 10; int* p; p = &a; cout << *p << endl;// 解引用 10 // 所有指针类型在32位操作系统下是4个字节 cout << sizeof(p) << endl; // 4 cout << sizeof(char*) << endl; // 4 cout << sizeof(float*) << endl; // 4 cout << sizeof(double*) << endl; // 4 system("pause"); return 0; }
空指针和野指针
空指针
-
空指针:指针变量指向内存中编号为0的空间;
-
用途:初始化指针变量;
-
注意:空指针指向的内存是不可以访问的;
-
示例:
#include <iostream> using namespace std; int main() { int* p = NULL; // 访问空指针报错 // 引发了异常: 读取访问权限冲突。p 是 nullptr // 内存编号0 ~255为系统占用内存,不允许用户访问 cout << *p << endl; system("pause"); return 0; }
野指针
-
野指针:指针变量指向非法的内存空间
-
示例:
#include <iostream> using namespace std; int main() { // 指针变量p指向内存地址编号为0x1100的空间 int* p = (int*)0x1100; // 访问野指针报错 // 引发了异常: 读取访问权限冲突。p 是 0x1100。 cout << *p << endl; system("pause"); return 0; }
空指针和野指针总结
- 空指针和野指针都不是我们申请的空间,因此不要访问。
const修饰指针
1.const修饰指针 — 常量指针
-
特点:指针指向可以修改,但是指针指向的值不可以修改
-
语法:
int a = 10; const int*p=&a;
-
p=&b正确;*p= 20错误
2.const修饰常量 — 指针常量
-
特点:指针指向不可以修改,但是指针指向的值可以修改
-
语法:
int a = 10; int * const p = &a;
-
p=&b错误;*p= 20正确
3.const即修饰指针,又修饰常量
-
特点:指针指向和指针指向的值都不可以修改
-
语法:
int a =10; const int * const p = &a;
-
p=&b错误;*p= 20错误
代码示例:
#include <iostream>
using namespace std;
int main() {
// 1. const修饰指针--- 常量指针
int a = 10;
int b = 10;
const int* p = &a;
// 指针指向可以修改
p = &b;
// 指针指向的值不可以修改
// *p = 20; // 错误
// 2. const修饰常量--- 指针常量
int* const p2 = &a;
// 指针指向不可以修改
// p2 = &b; // 错误
// 指针指向的值可以修改
*p2 = 20;
// 3. const即修饰指针,又修饰常量
const int* const p3 = &a;
// 指针指向和指针指向的值都不可以修改
// p3 = &b; // 错误
//*p3 = 20; // 错误
system("pause");
return 0;
}
技巧:看const右侧紧跟着的是指针还是常量, 是指针就是常量指针,是常量就是指针常量。
指针和数组
-
作用:利用指针访问数组中元素
-
示例:
#include <iostream> using namespace std; int main() { // 指针和数组 // 利用指针访问数组中的元素 int arr[10] = { 1,2,3,4,5,6,7,8,9,10 }; cout << "第一个元素为:" << arr[0] << endl; int* p = arr; // arr就是数组首地址 cout << "利用指针访问第一个元素:" << *p << endl; p++; // 让指针向后偏移4个字节 cout << "利用指针访问第二个元素:" << *p << endl; int* p2 = arr; for (int i = 0; i < 10; i++) { //cout << arr[i] << endl; cout << "利用指针访问第 " << i + 1 << " 个元素:" << *p2 << endl; p2++; } system("pause"); return 0; }
指针和函数
-
作用:利用指针作函数参数,可以修改实参的值
-
示例:
#include <iostream> using namespace std; void swap1(int a, int b) { int temp = a; a = b; b = temp; } void swap2(int* p1, int* p2) { int temp = *p1; *p1 = *p2; *p2 = temp; } int main() { // 指针和函数 int a = 10; int b = 20; // 值传递 swap1(a, b); cout << "a = " << a << endl; // 10 cout << "b = " << b << endl; // 20 // 地址传递 // 如果是地址传递可以修饰实参 swap2(&a, &b); cout << "a = " << a << endl; // 20 cout << "b = " << b << endl; // 10 system("pause"); return 0; }
指针、数组、函数案例
-
案例描述:封装一个函数,利用冒泡排序,实现对整型数组的升序排序,例如数组:int arr[10] = { 4,3,6,9,1,2,10,8,7,5 };
-
代码示例:
#include <iostream> using namespace std; // 冒泡排序函数 void bubbleSort(int* arr, int len) //int * arr 也可以写为int arr[] { for (int i = 0; i < len - 1; i++) { for (int j = 0; j < len - 1 - i; 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[10] = { 4,3,6,9,1,2,10,8,7,5 }; int len = sizeof(arr) / sizeof(int); bubbleSort(arr, len); printArray(arr, len); system("pause"); return 0; }
-
总结:当数组名传入到函数作为参数时,被退化为指向首元素的指针。