一维数组指针
int a[10], *ptr;
ptr=a;或ptr=&a[0];
ptr+n与a+n表示数组元素a[n]的地址,即&a[n]。
*(ptr+n)和*(a+n)等效于a[n]。
ptr[n]等效于*(ptr+n)。
二维数组指针
int a[3][4], *ptr;
把二维数组看成n行一维数组,a[n]就是第n行的首地址。将每行的首地址传递给指针变量,行中的其余元素均可以由指针来表示。
&a[1][2]等效于a[1]+2。
ptr=a[1]等效于ptr=*(a+1)。
数组元素a[1]是一维数组的首地址(一个指向int型的指针)。
二维数组其实就是包含数组的数组。a[1]的元素类型是数组int [4],当访问数组元素a[1]时,编译器知道这是一个int [4]的数组(首地址)。
数组名不是变量,它只是一个记录地址的标签,在对元素的访问上所起的作用和指针一样。可以将二维数组名理解为指针的指针。
ptr=a; // 错误:int *与int (*)[4]的间接级别不同。a实际上是一个指向int [4]类型的指针。
int (*ptr)[4]=a; // 正确。一个指向4个元素的数组的指针,数组元素的数据类型为int。
在引用元素的时候,可以这样:(*ptr)[0],(*ptr)[1],(*(ptr+1))[0],(*(ptr+1))[1]。
指针数组
指针类型 *数组名[数组长度]
int *p[4];
由于[]比*优先级高,因此p先与[4]结合,形成p[4]的形式,这显然是数组形式。然后再与p前面的*结合,表示数组元素的数据类型为int *。
函数指针数组
函数返回值类型 (*数组名[])(形参列表)
*数组名[]外面的括号改变了默认的运算符优先级。圆括号和数组说明符的优先级相同,如果不用圆括号将指针数组说明表达式扩起来,根据圆括号和方括号的结合方向,*数组名[]()则会产生一个怪物:返回值类型为指针的函数数组。所以必须括起来,以保证数组的每一个元素是指针(指向函数入口地址)。
指针的指针
#include <stdio.h>
func(int **fp)
{
while(**fp != 0)
{
if(**fp == 7) break;
else (*fp)++;
}
}
main()
{
int a[10] = {1,2,3,4,5,6,7,8,9,0};
int *p = a;
printf("%d/n",*p);
func(&p);
printf("%d/n",*p);
}
指针的指针另一种用法是处理指针数组。有些程序员喜欢用指针数组来代替多维数组,一个常见的用法就是处理字符串。
#include <stdio.h>
main()
{
char *Names[] = {"Bill","Sam","Jim","Paul","Charles",0};
char **nm = Names;
while(*nm != 0) printf("%s/n",*nm++);
}
先用字符型指针数组Names的地址来初始化指针nm。每次调用printf()都首先传递指针nm指向的字符型指针,然后对nm进行自增运算使其指向数组的下一个元素(还是指针)。注意*nm++,++优先级高于*,该表达式等价于*(nm++),由于nm++是后缀增量运算,因此按自左向右的计算顺序,它首先取得指针指向的内容,然后使指针自增。
注意数组中最后一个元素被初始化为0,while循环以此来判断是否到了数组末尾。具有零值的指针常常被用做循环数组的终止符。程序员称零值指针为空指针(NULL)。采用空指针作为终止符,在数组增删元素时,就不必改动遍历数组的代码,因为此时数组仍然以空指针作为结束。
函数指针
函数返回值类型 (*指针变量名)(形参列表)
指针变量名和指针运算符外面的括号改变了默认的运算符优先级。如果没有圆括号,就变成了一个返回整型指针的函数的原型声明。注意:函数指针没有++和--运算。
int (*fptr)();
fptr=&function;
fptr=function;
取地址运算符&不是必需的,因为函数标识符就表示了它的地址。
x = (*fptr)();
x = fptr();
第二种格式看上去和函数调用无异。但是有些程序员倾向于使用第一种格式,因为它明确指出是通过指针而非函数名来调用函数的。
#include<stdio.h>
int max(int x,int y){return(x>y?x:y);}
void main()
{
int a,b,c;
int (*ptr)(int,int);
ptr=max;
scanf("%d,%d",&a,&b);
c=(*ptr)(a,b);
printf("a=%d,b=%d,max=%d",a,b,c);
}
void (*)(); // 只声明了数据类型
unsigned psize = sizeof(void (*)()); // 获得函数指针大小。
char (*pfv)(int);
typedef void (*pfv)(); // 定义数据类型,类型名为pfv,即一个指向特定函数的指针。
pfv ptrfv;
LPCTSTR,LPWSTR,PTSTR,LPTSTR
L:表示long指针,在Win32中以及其他的32位操作系统中,long指针和near指针及far修饰符没有实际意义。long,near,far与普通指针没有区别,LP与P是等效的。
P:表示这是一个指针。
T:表示_T宏,这个宏用来表示你的字符是否使用UNICODE。如果你的程序定义了UNICODE或者其他相关的宏,那么这个字符或者字符串将被作为UNICODE字符串,否则就是标准的ANSI字符串。
STR:表示这个变量是一个字符串。
C:表示是一个常量,const。
W:表示宽字符。
指针
最新推荐文章于 2015-10-20 21:11:08 发布