C++指针详细讲解

目录

一、计算机程序在存储数据时的三要素

二、内存的四个区

三、指针变量的3个基本定义

四、指针的声明与初始化

五、指针的危险

六、指针的四种运算

七、指针与多维数组

八、指针的引用

九、动态分配内存

十、指针和函数(数组和函数)

十一、指针和const


一、计算机程序在存储数据时的三要素

  • 信息存储在何处
  • 存储的值是多少
  • 存储的信息是什么类型

二、内存的四个区

  • 代码区,存储代码片
  • 全局区,存储全局的常量,比如:字符串常量“abcdefg”、static、const
  • 栈区,系统自动开辟的,不大,比如:for (int i = 1; i <= n; i++)此处的局部变量 i 所占用的内存空间是系统自动开辟的
  • 堆区,动态开辟,手动释放,很大,比如:new,delete

三、指针变量的3个基本定义

  1. 地址:把内存以单个字节为单位分割,每个字节编号,这个编号就是地址。a) 编号连续 b) 唯一  c) 取地址符‘&’:单目运算符,优先级只比'()'、'[]'、'.'低;结合顺序:右向左。
  2. 首地址:一段内存空间中第一个存储单元的地址。(此处存储单元:低维度数组)。
  3. 指针变量:用来存放地址的变量,占用4Bytes内存。

四、指针的声明与初始化

/*
指针声明
*/
int* ptr; // ptr的类型是指向int的指针,或者ptr的类型是int*
double* dptr; // dptr的类型是指向double的指针,或者dptr的类型是double*
/*
指针初始化
*/
int variable = 10;
int* ptr = &variable;

五、指针的危险

在C++中创建指针的时候,计算机将分配用来存储地址的内存,但是不会分配用来存储指针所指向的内存,因为为数据提供空间是一个独立的步骤。

  • 野指针:不能明确指向的指针变量
  • 空指针:void* 可以先这么定义然后转换成其它的数据类型

WARNING:一定要在对指针应用解除引用运算符' * '之前,将指针初始化为一个确定的、适当的地址。

/*
使用错误,23333不是一个已经分配了内存空间的变量,int* 类型的指针ptr只是一个存储地址的4B空间
*/
int* ptr;
*ptr = 23333;
/*
定义void* 类型指针ptr,赋值 a 的地址,然后将 void* 类型转化为 int* 类型的指针并通过
解除引用运算符‘*’进行数值输出 
*/
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
	void* ptr;
	int a = 3;
	ptr = &a;
	
	cout<< *(int*)ptr<< endl;
	return 0; 
}

六、指针的四种运算

指针只有四种运算:' + '、' -  '、' ++ '、' -- ',偏移。

指针变量的加减,以指针所指向的类型空间为单位进行偏移。

例如:

  • char* ptr;         char的大小是 1B,因为 ptr 的类型为 char*,所以 ptr+1 的偏移量是 1B
  • int* ptr;            int的大小是4B,因为 ptr 的类型为 int*,所以 ptr+1 的偏移量是 4B
  • double* ptr;     double的大小是8B,因为 ptr 的类型是 double*,所以 ptr+1 的偏移量 8B
#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
	int a[5] = {1, 2, 3, 4, 5};
	// 数组名表示首地址
	cout<< "a= "<< int(a)<< endl;
	cout<< "a+1= "<< int(a+1)<< endl;
	
	// 对数组进行取地址 &,得到的并不是数组的首地址,而是整个数组,也就是 int(*)[5] 
	cout<< "&a = "<< int(&a)<< endl;
	cout<< "&a+1 = "<< int(&a+1)<< endl;   
	return 0; 
}

输出:
a = 2686684
a+1 = 2686688 // 首地址a[0],故而a的类型是int*,所以a+1增加4B
&a = 2686684
&a+1 = 2686704 // &a的类型是int(*)[5],所以&a+1增加4x5=20B

七、指针与多维数组

int a[1][2][3][4][5][6][7][8];

多维数组:从高维到低维拆
&a8维int(*)[][][][][][]
a7维int(*)[][][][][]
a[]6维int(*)[][][][]
a[][]5维int(*)[][][]
a[][][]4维int(*)[][]
a[][][][]3维int(*)[]
a[][][][][]2维int*
a[][][][][][]1维int

 

 

 

 

 

 

 

 

 

八、指针的引用

  • 下标法 a[m][n]
  • 指针法 *(a[m] + n) 或者 *(*(a + m) + n)

九、动态分配内存

C++的new运算符,将找到一块长度正确的内存块,并返回该内存块的地址。

int* p = new int;             // 分配一个int大小的空间
char* p = new char;           // 分配一个char大小的空间
int* p = new int[32];         // 分配一个长度为32的int数组的空间
char* p = new int[32][32];    // 分配一个大小为32x32的char二维数组的空间

delete p;     // 释放空间
delete[] p;   // 释放数组空间

new和delete要搭配使用。使用new运算符在自由存储空间(或者堆)上创建变量之后,没有调用delete,即使包含指针的内存由于作用域规则和生命周期的原因被释放,但是在自由存储空间上动态分配的变量或者结构依然存在。

十、指针和函数(数组和函数)

/*
get_variable函数和show_arr函数中的第一个参数 int arr[]和int* arr都表示arr是一个
int类型的指针 
*/
#include<iostream>
#include<cstdio>
using namespace std;
void get_variable(int arr[], int length)
{
	for (int i = 0; i < length; i++)
	{
		arr[i] = i+1;
	}
}

void show_arr(const int* arr, int length)
{
	for (int i = 0; i < length; i++)
	{
		cout<< arr[i]<< " ";
	}
	cout<< endl;
}

int main()
{
	int arr[5];
	
	get_variable(arr, 5);
	show_arr(arr, 5); 
	
	return 0;
}

十一、指针和const

  • 指针指向一个const对象(常量对象):防止指针更改所指向的值
  • 将指针本身声明为const(常量):防止指针指向其它的位置
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值