c++踩坑大法好 之 指针
1,指针的理解
指针可以理解为一种特殊变量,
一般的变量,如int aa=1;这种,变量储存的是值(也就是1),用地址运算符获取变量在内存中的地址,但是指针不一样,
指针储存的是地址,将接触引用运算符(*,又叫间接值运算符)用于指针,就能拿到该地址处储存的值。
基础实例请看:
#include "pch.h" using namespace std; int main() { int value = 6; int *pvalue; //声明一个指针 pvalue = &value; //把value的地址赋值给pvalue指针 value = 7; printf("%d\n", *pvalue); //打印出来的数字为7,也就是说value的地址上的值变了,那么指向该地址的指针的取值也会变化。 *pvalue = 9; printf("%d\n", value); //打印出来value的值为9,*pvalue=9的意思是,对pvalue所储存的地址的值赋值为9,而这个地址的值所对的变量正事value,所以它也会改, return 0; }
注意术语:*pvalue是int,pvalue是指向int的指针,
2,星号跟谁走?
跟谁走都可以,这不会报错,但是强调重点不同
int *ptr; //c风格,强调的是*ptr是int类型 int* ptr; //强调ptr属于一种复合类型:int*,读为指向int的指针 //注意,注意 int* ptr,hehe; //这种写法实际上声明了一个指针和一个int,所以个人推荐星号跟着变量名走,防止引发以上错误。
3,指针传参,引用传参
1,局部变量的值改了,全局变量的值不会改
#include <iostream> using namespace std; int test(int xc); int main() { int t2 ; t2 = 2; test(t2); printf("quanju %d\n", t2);//打印为:2 return 0; } int test(int xc) { int t1 = 1; xc = t1; printf("jubu %d\n",xc); return 0; } //把一个int变量的值传递给函数,函数内部改变了值,函数运行的时候值确实改变了,但是结束以后,外部值没有发生变化
2,引用的值变了,被引用的值也变了。
#include <iostream> using namespace std; int test(int &xc); int main() { int t2 ; t2 = 2; test(t2); //此处相当于int &xc=t2;xc这个变量现在是t2的引用,引用的意思就是你变我也变 printf("quanju %d\n", t2);//打印为:1 return 0; } int test(int &xc) { int t1 = 1; xc = t1; printf("jubu %d\n",xc); return 0; } //把一个int变量的引用传递给函数,函数内部改变了变量的引用的值,函数运行结束以后,外部值也变了。
3,通过指针修改了被指向的区域的值,全局和局部变量都变了
#include <iostream> using namespace std; int test(int *xc); int main() { int t2 ; t2 = 2; test(&t2); //此处相当于int *xc=&t2;int型指针xc这个变量现在指向的是t2的地址,指向的意思是变量前面加上星号就能得到指向的区域的内容 printf("quanju %d\n", t2);//打印为:1 return 0; } int test(int *xc) { int t1 = 1; *xc = t1; printf("jubu %d\n",*xc); return 0; } //把一个int变量的地址传递给函数,函数接收为int类型的指针,内部改变了指针指向的内存区块的值,函数运行结束以后,外部值也变了。
4,仅仅是在局部把指针的指向变了,局部变量确实变了,但是全局变量没有改变
#include <iostream> using namespace std; int test(int *xc); int main() { int t2 ; t2 = 2; test(&t2); //此处相当于int *xc=&t2;int型指针xc这个变量现在指向的是t2的地址,指向的意思是变量前面加上星号就能得到指向的区域的内容 printf("quanju %d\n", t2);//打印为:2 return 0; } int test(int *xc) { int t1 = 1; xc = &t1; //xc是个地址,*xc是个值,通过修改xc的地址,改了xc的指向(原本指向t2,现在指向t1) printf("jubu %d\n",*xc); return 0; } //把一个int变量的地址传递给函数,函数接收为int指针,局部修改了指针的指向,并没有影响到全局变量。
4,使用new来创建指针
指针普通使用方法如下:
int a=1; //创建一个内存空间,名字叫a,内部存储的是int类型,1 int *ptr=&a; //创建一个int型指针,指向a的地址。 //现在对于变量a和其中储存的1来说,除了变量本身能够访问这个有名称的内存外,ptr也可以访问。
1),使用new为指针分配内存空间:
int *ptr=new int; //创建int型指针ptr,并且为该指针分配一个int大小的内存空间。 *ptr=2; //把2这个值存储到指针指向的内存中去。 //new方法和普通方法的区别在于,普通指针指向一个变量,变量有名称有值有内存空间,而new方法指向的是一个数据对象,它没有名称有值有内存空间,除了指针以外,不能被访问,另外,ptr的值在栈中,而new会从堆的内存区分配。
2),使用new的指针需要自行释放内存空间------使用delete:
int *ptr=new int; delete ptr; //new出来的指针使用完毕后记得释放,即使是释放空指针也没问题,但是不能多次执行delete释放同一个变量,也不能释放非new创建的指针 int *pt=new int[500]; //new去创建一个包含500元素的int数组,然后把第一个元素的指针赋值给pt delete [] pt; //如果执行delete pt,系统一看pt是个int型的指针,然后闻着味就仅仅把数组第一个元素释放掉了,只有告诉系统这个是想释放整个数组:delete [] pt才能真正释放掉数组
3),new创建的指针数组如何使用?
#include <iostream> using namespace std; int main() { int *pt = new int[10]; pt[0] = 1; pt[1] = 2; //既然是指针,按理说pt是个地址,但是c++同时也把它当作一个数组名来使用,所以说以上写法是合法的 printf("first:%d \n", *pt); //pt是指向第一个元素的地址,所以打出来是第一个元素的值 pt = pt + 1; printf("second:%d \n", *pt); //把pt当成一个地址,对其加一,将指向第二个元素(实际上是加了四个字节,因为是int),这时候打出来的是第二个元素的地址 pt = pt - 1; delete [] pt; //在释放以前必须保证pt是指向首元素的 return 0; }

浙公网安备 33010602011771号