指针是其值等于一个内存地址的一个变量。它“指向”内存中的一个位置。可以通过在声明中,在变量名前面放置一个*,将一个变量声明为一个指针变量。如下的代码把pPointerInt声明为指向内存中保存一个整数的变量:
int *pPointInt;
一元运算符&(“取址”运算符)用来获取一个变量的地址,以便将其存储到一个指针变量中。如下的代码将指针变量b的值设置为整数变量a的地址:
int a = 9;
int *b;
b=&a;
代码解释:
第一行将a声明为一个int变量,编译器拿出4个字节来存储a,并且将其初始化为9。
第二行将b声明为一个指向int的指针。
第三行使用取址运算符&来获取a的地址,然后将a的地址赋值给b。
假设编译器分配的起始地址为1048880,那么代码的过程如下图:
一元运算符*(叫做“求值”或“解引用”运算符),通过使用指向一个内存位置的指针变量,老设置或者获取内存位置的内存。可以这样看,把表达式*pPointInt看作是一个别名,即针对存储在pPointInt的内容中的任何内存位置的另一个名称。表达式*pPointInt可以用来设置或者获取该内存位置的内容。
在如下的代码中,将b设置为a的地址,因此,*b变成了a的别名:
int a;
int c;
int *b;
a = 9;
b = &a;
c = *b;
*b = 10;
指针在 C 中用来引用动态分配的内存。指针也用来避免将大块的内存,
例如数组和结构(将在本章稍后介绍),从一个程序的一部分复制到另一部分。例如,可以 把指向结构的一个指针传递给函数,而不是把一个较大的结构传递给函数。函数随后使用指 针来访问结构。随后我们还会看到,Objective-C 对象也总是通过指针来引用。
通用指针
声明为 void 的指针变量,是一个通用指针。
1. void *genericPointer;
可以将通用指针设置为任何变量类型的地址:
1. inta=9;
2. void *genericPointer; 3. genericPointer = &a;
然而,试图从一个通用指针获取一个值,将导致一个错误发生,因为编译器没办法知道 如何解释通用指针所表示的地址的字节:
1. inta=9;
2. int b;
3. void *genericPointer;
4. genericPointer = &a;
5. b = *genericPointer; // WRONG - won't compile
要通过 void*指针获取一个值,必须将其转换为指向一个已知类型的指针:
1. inta=9;
2. int b;
3. void *genericPointer;
4. genericPointer = &a;
5. b = *((int*) genericPointer) ; // OK - b is now 9
强制转换运算符(int*)迫使编译器将 genericPointer 看做是指向一个整数的指针 。
C 不会检查一个指针变量是否指向内存的一个有效区域。在 C 编程中错误地使用指针, 可能会比其他错误原因引发更多的程序崩溃。