神奇的C++——指针
前言
学过C++或者C的同学可能都知道,它们和java、python这些最不一样的就是拥有指针——高级而又强大。
今天看书的时候,又看到了关于指针的内容,想起记录下来,或多或少留点记录。不周全的以后再补充啦
概念
指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。地址指向一块内存,可以用来存储数据。什么数据呢?讲道理,只要是数据都可以存储,int、long、char、double、结构体、类…
所以可以吧指针看作一个指示性的东西,自己本身指存储地址,就像钥匙,地址指向的才是重要的数据,就好比粮仓。
但是也不能说指针不重要,钥匙怎么能不重要,所以都重要。
初识
我们用一个最简单的例子来初识一下指针
#include<iostream>
using namespace std;
int main()
{
int donuts=6;
int* dp=&donuts;
cout<<"dp="<<dp<<" *dp="<<*dp<<endl;
return 0;
}
结果
可以看到指针dp指向了变量donuts,更本质的讲是指向了,存储了6的那块地址,也就是dp=后面那一长串的地址。
这里&是取值符号,将donuts的地址取出来赋值给dp;* dp这里的 * 是解引用,将指针指向的的内存存储的数据读取出来。
从这个小例子可以基本看出指针的用法了,如何声明,如何使用。
注意:这里int* 表示int型的指针,虽然指针存储的都是64位的地址(在64位操作系统上),但是为了却分它们指向的数据类型,还是要予以区分
声明
前面初识的时候已经略知一二。现在正式讲一讲。
由于计算机需要跟踪指针指向的值的类型,比如有的指向int,有的指向char,所以需要根据内部值进行区分。
好比又要几把钥匙,好几个粮仓,钥匙都一样,但是我需要区分,这把是开谷仓的,这把是开豆仓的等等
因此命名为:
类型* 名称
书写规则
这里要说明的是* 运算符两边的空格是可选的,传统上,C程序员使用的是:
int *ptr;
强调的是*ptr是一个int类型的值
而C++程序员更多的使用的是这种格式:
int* ptr;
强调的是int*是一种类型——指向int的指针
在哪里添加空格对于编译器而言没有任何区别,甚至可以
int*ptr;
但是有一点需要注意:
int* p1,p2;
像这样的命名,p1是指针,p2却是一个int。
也就是说每个指针的变量名,都需要使用一个*
初始化
可以在声明的时候就初始化,但是需要记住的一点就是:被初始化的是指针,而不是它指向的值
int higgens=5;
int* pt=&higgens;
这里是将pt(而不是*pt)的值设置为&higgens
例子:
#include<iostream>
using namespace std;
int main()
{
int higgens=5;
int* pt=&higgens;
cout<<"higgens的值为:"<<higgens
<<"; higgens的地址为:"<<&higgens<<endl;
cout<<"*pt的值为:"<<*pt
<<"; pt的值为:"<<pt<<endl;
}
输出:
可以看出将pt初始化为higgens的地址
指针的危险
我们需要记住极其重要的一点是:在C++创建指针时,计算机将分配用来存储地址的内存,但是不会分配用来存储指针所指向的数据的内存。为数据提供空间是一个独立的步骤。
比如:
long* fellow;
*fellow=23333;
乍一看没啥问题,但是仔细想想,就会看出端倪
fellow的确是一个指针,但是指向哪里呢?由于没有初始化,那么系统就会随机赋一个地址给它,可能是程序代码的地址,可能是数据的地址,所以一旦随意篡改,那么很有可能造成很大的问题。
这是一个非常严重的问题,所以需要十分注意!
今天先说到这里啦,后面的以后再补充~