指针的声明:
数据类型* 指针变量名
e.g:
int* p;
星号两边的空格无关紧要,并不影响指针的声明:
int* p;
int * p;
int *p;
这几者都是一样的,等价的
注意:指向还没有初始化内存的指针可能会产生问题。如果将这种未初始化的指针进行解引,指针的内容会是一些不合法的数据,造成程序的异常。
地址操作符 &
地址操作符& 返回操作数的内存地址。这个内存地址可以用来初始化指针。
例如:
int num = 10;
int* p = #
//对数据num取内存地址,并赋值给指针p。 p的值就是存放num数据的内存地址
//p的数据类型为: int* 类型的指针 , num的数据类型则为int
解引指针 *
解引指针使用*号操作符。解引将返回指针指向的内存地址的数据。即指针的值(另一个变量的内存地址)所在的位置储存的数据。
例如:
上例中: int numval = *p;
//对指针p进行解引操作,并且赋值给numval,
//变量numval的值就是p指针指向内存地址的那个数据。即num的值10.
null 指针
null 指针与未初始化的指针:
1. null指针表示该指针不指向内存中的任何地址
2. 未初始化的指针可能包含任何值,会随意指向内存中的某一个地址。
3. 在c中 0 可以表示为null指针NULL
int* p1 = 0;
int* p2 = NULL;
void 指针
void指针的声明: void* p 表示这个指针p可以用来存放任何数据类型的引用。
注意:
1. 任何指针都可以被赋值给void指针,并且可以被转换为原来的指针
2. void指针和其他指针永远不会相等
3. 两个赋值为NULL的void指针是相同的
4. void指针只能作为数据的指针,不能作为函数指针
指针的长度
指针的长度是有其所在的机器和编译器来决定的。与指针的数据类型没有关系。
例如:
int num = 123;
double num2 = 123.4;
int* p=#
double* p1 = &num2;
//指针p.和p1 的长度是相同的。都可能占用的是4个字节。
指针的运算
-
声明指针
int p=NULL; -
*解引指针
int num = *p; -
-> 指向引用的成员数据
p->name -
+加
p++, p+1,p+2 -
-减
p–,p-1,p-2 -
== != 是否相等
p1 == p2 -
< <= > >=大小
p1>=p2 -
(数据类型)转换
double vertor[] = {10,20,30,40,50,60};
double* p = vertor;
std::cout << *p << std::endl; //10
std::cout << p << std::endl; //0x7ffee37b6a20
std::cout << *p << std::endl; //10
p += 2;
std::cout << p << std::endl; //0x7ffee37b6a30
std::cout << *p << std::endl; //30
p ++;
std::cout << p << std::endl; //0x7ffee37b6a38
std::cout << *p << std::endl; //40
指针的加减:
1. 两个指针加减,表示指针之间内存地址的差值。
2. 指针本身加减,表示指向下一个指针内存,大小为指针类型的大小乘以加减的数值。
3. void 指针不可以进行加减操作。
常量与指针
- 指向常量的指针: const int * p
表示指针指向的数据是一个常量,是不可以更改的,但是指针本身是可以更改的,即指针可以指向其他的地方。 - 指向非常量的常量指针:int* const p
表示指针本身是一个常量,是不可以更改的,但是指针指向的数据是一个变量,这个变量是可以更改的,即指针本身的指向不可以更改,但是其指向的数据是可以更改的 - 指向常量的常量指针: const int* const p
表示指针和指向的数据否是常量,二者进行了绑定,不可以再进行更改。 - 指向“指向常量的常量指针”的指针:const int * const * p
表示3的升级版,是一个直线指针的指针