计算机内存以字节为最小单位进行编址的。
1、地址就是内存单元的编号。
2、指针就是地址,地址就是指针。
3、指针变量是存放地址(也就是指针)的变量。指针和指针变量是两个不同的概念。
4、但是要注意,通常我们叙述时会把指针变量简称为指针,实际他们含义并不一样。
int i; int *p; //p是变量的名字,p变量的数据类型是int*。int * 表示p变量存放的是int型变量的地址。 p = &i; //ok /* 1、p保存了i的地址,因此p指向i。 2、p不是i,i也不是p。修改i的值不影响p的值,修改p的值也不影响i的值。 3、如果一个指针变量指向一个普通变量(即指针变量存放普通变量的地址),则 *指针变量 就完全等同于 普通变量 4、*p就是以p的内容为地址,空间存储的变量 */ p = i; //error,因为类型不一致,p只能存放int类型变量的地址,不能存放int类型的值。
1、表示一些复杂的数据结构
2、快速传递数据
3、使函数返回一个以上的数据
void f(int *pa, int *pb) { *pa = 1; *pb = 2; //被调函数修改主调函数的值----指针可以做到,其他做不到 } int main(void) { int a = 6, b= 8; f(&a, &b); }
4、能够直接访问硬件
5、能够方便的处理字符串
6、是理解面向对象语言种引用的基础
内存单元的编号
从零开始的非负正数
范围:32位的最大访问空间是4G.
1、指针的本质就是一个操作受限的非负整数(指针可以相减,不能进行相加,相乘,相除运算)
2、指针存放的是地址,地址是一个4字节大小(32位机器)的非负整数。不管数据类型有多大,指针只保留这个数据起始第一个字节的地址(数据类型决定每个数据在内存中所占字节的大小),所以任何类型的指针都是4字节大小。
指针的常见错误
int main(void) { int *p; //局部变量不初始化,存放的是垃圾值 int i = 5; *p = i; //把i的值赋值给一个以垃圾值为地址的内存里。在这个程序里系统只分配了2个数的操作空 间(p,i),但在程序运行过程中操作了分配空间以外的空间。 printf("%d\n", *p); return 0; }
int main(void) { int i = 5; int *p, *q; p = &i; *q = p; //q为int*类型,则*q为int类型,p为int*类型,类型不一致不能进行赋值,出现语法错误 return 0; }
/* q的空间是属于本程序的,所以本程序可以读写q的内容,但如果q内部是垃圾值,则本程序不能读写*q的内容(也就是以q内容为地址的空间里的内容),因为此时*q代表的内存单元的控制权限并没有分配给本程序。 */ int main(void) { int i = 5; int *p, *q; p = &i; p = q; printf("%d\n", *p); //error:因为q本身系统分配空间(但p的值是q局部变量里的垃圾值), 但*p是一个垃圾值地址内的内容(超出系统分配的空间)。 printf("%d\n", *q); //error:操作q本身没有问题,但操作*p就越界了。 return 0; }
互换2个数
#include <stdio.h> void Huhuan(int *pa, int *pb) { int c; c = *pa; *pa = *pb; *pb = c; } int main(void) { int a = 3; int b = 4; printf("*pa = %d, *pb = %d\n", a, b); printf("///\n"); Huhuan(&a, &b); printf("*pa = %d, *pb = %d\n", a, b); return 0; }
1、乘法 2、定义指针变量 int *p; 定义了一个名字是p的变量,int* *表示p只能存放int类型变量的地址。 3、指针运算符 该运算符放在已经定义好的指针变量的前面; 如果p是一个已经定义好的指针变量,则*p就是以p内容为地址空间内存放的变量。
1、实参必须是该普通变量的地址 2、形参必须为该类型指针变量变量. 3、在被调函数中通过 *形参名 = ...... 的方式就可以修改主调函数相关变量的值。
一维数组名是一个指针常量,它存放的是一维数组第一个元素的地址。
//错误 int a[5]; b[3]; a = b; //error,一维数组名是一个指针常量
#include <stdio.h> int main(void) { int a[3]; printf("%#X\n", &a[0]); printf("%#X\n", a); } //运行结果 fuchunjie@FCJ:/mnt/hgfs/VMshare/mySpace/指针互换2数$ ./app 0XD5E2C42C 0XD5E2C42C //证明:一维数组名是一个指针常量,它存放的是一维数组第一个元素的地址。
如果p是一个指针变量,则p[i] 永远等价于 *(p+i);