内存和地址
1.内存中每个位置都是一个独一无二的地址标识(变量的地址);
2.内存中的每个位置都包含一个值(变量的值);
变量名通常有两方面的含义
(1)存储该变量的地址;
(2)该变量的值;
注意:名字与内存位置之间的关联并不是硬件所提供的,它由编译器为我们实现。所有这些变量为我们提供一种更方便的方法记住地址——硬件扔然是通过地址访问变量
指针变量的内容
变量的值就是分配给这个变量的内存位置所存储的值,一个变量被声明为指针并不改变其求值方式。
int a = 112,b = -1;
float c = 3.14;
int *d = &a;
float *e = &c;
在上述代码中,变量d和e的值不能错误的以为是存储于变量d和e内存位置的值112和3.14,应该是变量a的地址&a和变量c的地址&c。
间接访问操作符
通过一个指针变量访问它所指向的地址的过程称为间接访问或解引指针访问.
“*”
*d = 112;
*e = 3.14;
间接访问操作符(“”)需要一个右值*操作数,但它的结果是一个左值。
未初始化和指针非法引用
对指针进行访问前,必须非常小心,确保他们已经被初始化。
NULL指针:NULL为一个特殊的指针,表示不指向任何位置,对一个NULL指针进行解引用操作是违法的。
定义指针的时候要么显示的初始化指针,要么将指针初始化为"NULL"指针。
指针,间接访问和左值
指针变量可以做左值,并不是因为他们是指针,而是因为他们是变量。
int a;
int *d = &a;
表达式 | 左值 | 指定的位置 |
---|---|---|
a | 是 | a |
d | 是 | d |
*d | 是 | a |
指向指针的指针
先看如下代码:
int a = 12;
int *b = &a;
int **c = &b
表达式 | 相当的表达式 |
---|---|
a | 12 |
b | &a |
*b | a,12 |
c | &b |
*c | b,&a |
**c | a,12,*b |
指针运算
- 加/减法运算
公式:指针 + / - 整数
指针加上一个整数的结果是另一个指针,整数在执行加法运算前始终会根据合适的大小进行调整,这个“合适的大小”就是指针所指向的类型的大小,“调整”就是整数值和“合适的大小”相乘。
如 int * p;p+3增加3*sizeof(int)=12个字节,而不是3字节。
数组中的元素存储于连续的内存位置中,后面的元素的地址大于前面元素的地址。
- 指针 - 指针
只有当两个指针都指向同一个数组中的元素,才允许一个指针减去另一个指针,两个指针相减的结果类型是ptrdiff_t,他是一个有符号整数类型,减法运算的结果是两个指针之间的距离(以数组元素的类型为单位,而不是以字节为单位),因为减法运算的结果将除以数组元素的类型。
两个指针所指的不是同一个数组元中的元素,那么它们相减的结果是未定义的。
- 关系运算符
<= < >= >
指针的关系运算符的前提是它们都指向同意数组中的元素,比较表达式告诉你哪个指针指向更前或更后的元素。
然而两个任意的指针(不一定非要指向同一数组中的元素)可以进行相等或不相等的测试因为这类比较的结果和编译器在何处存储数据并无关系,——指针要么指向同一个地址,要么指向不同的地址。