指针的作用:通过指针间接访问内存(指针即是地址)

定义一个指针:语法:数据类型 *指针变量名;

实例代码:

#include <iostream>
#include "sum.h"
using namespace std;

int main() {
	int a = 5;
	//定义一个指针
	int* p;
	//让指针指向变量a的地址
	p = &a;
	//通过指针仿真变量a
	*p = 10;
	cout << "变量a的地址为:" << &a << endl;
	cout << "指针p的指向地址为:" << p << endl;
	cout << "*p = 10 之后a的值:" << a << endl;

}


#include <iostream>
#include "sum.h"
using namespace std;


int main() {
	int a = 5;
	//定义一个指针
	int* p;
	//让指针指向变量a的地址
	p = &a;
	//通过指针仿真变量a
	*p = 10;
	cout << "变量a的地址为:" << &a << endl;
	cout << "指针p的指向地址为:" << p << endl;
	cout << "*p = 10 之后a的值:" << a << endl;

}

指针的理解:

①将指针视为指定的量,而将值视为派生量,指针用于存储值的地址,因此,指针名(单单一个名,不带*)表示的是地址,*运算被称为间接值或解除引用运算符,

指针的危险性

long * fellow;
*fellow = 223323;
*fellow确实是一个指针,但是没有给这个指针赋予一个地址,所以这个指针将会被解释为存储值为223323的地址,如果这个时候我们的自己使用的变量用到的地址恰好是这个地址,那么这个时候就会出现难以调试的bug,因此,一定要在对指针进行解除引用运算符(运算)之前,将指针初始化为一个确定的、适当的地址。

内存分配

①在C语言中可以使用malloc进行内存的分配,在C++中仍然可以使用这个方法,但是还有更好的方法:new运算符
②int * p = new int;
new int告诉程序,需要适合存储int的内存,new运算符根据类型确定需要多少字节的内存,然后它找到这样子的内存空间只会,返回地址给p,p是被声明的一个int型指针,现在p就是一个地址,*p就是指向存在改地址的具体值。

定义变量和指针的区别

new分批的内存块通常与常规变量声明的分配的内存块不同,变量的值都存储在栈(stack)的内存区域中,而new从堆(heap)或自由存储区(free store)的内存区域分配内存(后面会讲述四大内存区)

使用delete释放内存

①当需要内存时,可以使用new来请求,这只是C+f内存管理数据包中有魅力的一一个方面。另-个方面是delete运算符,它使得在使用完内存后,能够将其归还给内存池,这是通向最有效地使用内存的关键一步。归还或释放(free)的内存可供程序的其他部分使用。使用delete时,后面要加上指向内存块的指针(这些内存块最初是用new分配的):

②注意点:
1)delete p;这将会释放指针p指向的内存,但是不会删除p指针本身,指针p还可以重新指向一个新分配的内存块,所以一定要配对使用new和delete,否则可能会出现内存泄漏,也就是说被分配的内存无法再也无法使用,严重的结果将会导致程序终止
2)只能用delete来释放使用new分配的内存,同时,对空指针使用也是安全的

指针和数组(这个内容有点花里胡哨,但是很实用)

①两种创建数组方式的比较:
1)如果是使用声明的方法去定义一个数组,那么程序在编译的时候将会为其分配内存空间,无论是程序是否使用到 数组,它都占用了一定的内存,在编译的时候给数组分配内存被称为静态联编
2)使用new的时候,如果在运行阶段需要用到数组,则创建它,如果不需要则不创建,还可以在程序运行的时候选择数组的长度,这被称为动态联编,以为这数组是在程序运行的时候创建的,这种数组被称为动态数组。

②使用new创建动态数组:
1)int * psom = new int[10]; new运算符返回第一个元素的地址,在这例子中,此地址被赋给了指针psome。
③使用new和的delete应该遵守的规则
1)不要使用delete来释放不是new分配的内存
2)不要使用delete释放同一个内存块两次
3)如果使用new[ ]为数组分配内存,则应该使用delete [ ]的方式来释放
4)如果使用new[ ]为一个实体分配内存,则应该使用delete(无[ ])来释放
5)对于空指针使用delete是安全的
④使用动态数组
1)使用动态数组可以使用 指针名[下标] 的方式进行访问
假设指针名为p,则p[1] 和 *(p+1) 是一样的,都可以访问到数组的第二个元素

结构体数组、结构体指针

(1)结构体数组
①使用数组名[下标].成员变量的方法访问

#include <iostream>
#include "sum.h"
using namespace std;

struct mytype
{
	int age;
	char money[10];
};

int main() {
	mytype test1[10];
	test1[0].age = 10;
	test1[2].age = 20;
	cout << test1[0].age << test1[2].age << endl;
}

(2)结构体指针
①访问方式区别于上面,不能直接使用句点的方式,需要使用箭头指向的方法:->

#include <iostream>
#include "sum.h"
using namespace std;
struct mytype
{
	int age;
	float money;
};

int main() {
	//定义结构体指针
	mytype* ps = new mytype;
//ps只是一个地址,无法使用 . 的方法访问成员变量,可以使用箭头指向方式进行访问  ->
	ps->age = 10;
	cout << ps->age <<endl;
	//此外还可以通过以下方式进行访问
	(*ps).age = 20;
	cout << ps->age << endl;
}

指针的递增递减运算

掌握的关键是要非常的清楚那个运算符优先级更高一点,根据优先级一步一步的去运算

①递增递减:
1)i++:先引用i的值,再进行加一,++i:先加一再引用。
②优先级:* 、++i、–i的优先级相同,从右到左结合,i++、i–优先级比上面的三个要高
③运算:
1)++p:先进行p++,指针地址往后,再使用获取对应地址的值
2)++*p:先获取当前p所指向地址的值,在将指针往后加一个单位的字节内存
3)(*p)++:括号优先级max,本质:对当前地址的实际值进行加一操作
4)*p++:++优先级max,本质:取p指向地址的下一个地址的值

变量存储

①自动存储:函数内部定义的变量称为自动变量,生命周期为函数的生命周期,这种变量一般存储在栈当中,运行到代码块的时候,变量依次加入到栈当中,代码块结束的时候,按相反的顺序释放变量,遵循后进先出(LIFO)的原则,因此栈将不断的增大和减小
②静态存储:函数外部声明和static关键字声明
③动态变量:对应的是管理一块内存池,也叫做自由存储空间(堆),在这里面静态变量和自动变量是分开的

指针的东西暂时到这,后面学习到其它的内容在对博客进行补充

附上几张好看的壁纸

分享一个网站,可以免费下载高清的各种壁纸
高清壁纸无广告下载
C++基础学习---->指针基础笔记_程序开发
C++基础学习---->指针基础笔记_C  _02
C++基础学习---->指针基础笔记_程序开发_03