- 指针即内存地址,也被称为指针变量,大小为4个字节(或8个字节)的变量。
- 指针变量是用来存放内存地址的变量。
- 通过指针,能够对该指针指向的内存区域进行读写。
- 如果把内存的每个字节都想象成宾馆的一个房间,那么内存地址相当于就行房间号,而指针里存放的,就是房间号。1
2
类型名 *指针变量名 T *pT可以是任何类型的名字,比如int,double
*p 等价于存放在地址p处的一个T类型的变量
* 间接引用运算符
ps: 通过表达式*p,可以读写从地址p开始的sizeof(T)个字节
int *p;//p是一个指针,变量p的类型是 int * char *pc;//pc是一个指针,变量pc的类型是 char * float *pf;//pf是一个指针,变量pf的类型是 float *3. 指针的用法
char ch1 = 'A'; char *pc = &ch1;//使得pc指向变量ch1
& : 取地址运算符
&x : 变量x的地址(即指向x的指针)
对于类型为T的变量x, &x 表示变量x的地址(即指向x的指针)
&x 的类型是 T *。
#include4. 指针的作用int main() { int a; int *p = &a; scanf("%d",&a); printf("a = %dn",a); scanf("%d",p); printf("a = %dn",a); return 0; }
有了指针,就有了自由访问内存空间的手段
- 不需要通过变量,就能对内存直接进行操作。通过指针,程序能访问的内存区域就不仅限于变量所占据的数据区域
- 在C++中,用指针p指向a的地址,然后对p进行加减操作,p就能指向a后面或前面的内存区域,通过p也就能访问这些内存区域
ps: 不同类型的指针,如果不经过强制类型转换,不能直接互相赋值
#includeint main(){ int a = 100; char str[20] = "KeproZ"; printf("%#X, %#Xn", &a, str); return 0; }
#include二、指针的运算 1. 指针基本运算int main() { char str[128]; printf("请输入英文单词:"); scanf("%s",str); printf("英文单词的地址是:%pn",str); return 0; }
- 两个同类型的的指针变量,可以比较大小
- 两个同类型的的指针变量,可以相减
p 1 − p 2 = ( 地址 p 1 − 地址 p 2 ) / s i z e o f ( T ) p1 - p2 = (地址p1 - 地址p2) / sizeof(T) p1−p2=(地址p1−地址p2)/sizeof(T) - 指针变量加减一个整数的结果是指针
p+n 指向地址: 地址p + n * sizeof(T) - 指针变量可以自增、自减
p++ ++p : p指向n + sizeof(T)
p-- --p : p指向n - sizeof(T) - 指针可以用下标运算符 [] 进行运算
p[n] 等价于 *(p+n)
#include三、空指针int main() { int *p1,*p2; int n = 4; char *pc1,*pc2; p1 = (int *)100; p2 = (int *)200; printf("%dn",p2 - p1);//输出25,因为(200-100)/sizeof(int)=25 pc1 = (char *)p1; pc2 = (char *)p2; printf("%dn",pc1 - pc2);//输出-100,因为(100-200)/sizeof(char)=-100 printf("%dn",(p2 + n) - p1); int *p3 = p2 + n;//p2+n是一个指针,可以用它给p3赋值 printf("%dn",p3 - p1); printf("%dn",(pc2 - 10) - pc1); return 0; }
- 地址0不能访问,指向地址0的指针就是空指针
- 可以用“NULL”关键字对任何类型的指针进行赋值。NULL实际上就是整数0,值为NULL的指针就是空指针:
int *pn = NULL; char *pc = NULL; int *p2 = 0;
- 指针可以作为条件表达式使用。如果指针的值为NULL,则相当于为假,值不为NULL,就相当于为真
i f ( p ) < = = > i f ( p ! = N U L L ) if (p) <==> if(p!=NULL) if(p)<==>if(p!=NULL)
i f ( ! p ) < = = > i f ( p = N U L L ) if (!p) <==> if(p=NULL) if(!p)<==>if(p=NULL)
C语言允许函数的返回值是一个指针(地址),我们将这样的函数称为指针函数。
#includevoid Swap(int *p1,int *p2) { int tmp = *p1; //将p1指向的变量的值,赋给tmp *p1 = *p2; //将p2指向的变量的值,赋给p1指向的变量 *p2 = tmp; //将tmp的值赋给p2指向的变量。 } int main() { int m = 3,n = 4; Swap(&m,&n); //使得p1指向m,p2指向n printf("%d %d",m,n); //输出4,3 return 0; }
- 指针对四个整数进行排序
#include五、指针和数组 1. 指针和数组的关系void psort(int *pa,int *pb,int *pc,int *pd) { int a[5],i,j,t; a[1]=*pa;a[2]=*pb;a[3]=*pc;a[4]=*pd; for(i=1;i<=3;i++) { for(j=1;j<=4-i;j++) { if(a[j] t=a[j]; a[j]=a[j+1]; a[j+1]=t; } } } *pa=a[1];*pb=a[2];*pc=a[3];*pd=a[4]; } int main() { void psort(int *pa,int *pb,int *pc,int *pd); int a,b,c,d; int *p1,*p2,*p3,*p4; scanf("%d %d %d %d",&a,&b,&c,&d); p1=&a;p2=&b;p3=&c;p4=&d; psort(p1,p2,p3,p4); printf("%d %d %d %d",a,b,c,d); return 0; }
- 数组的名字是一个指针常量,指向数组的起始位置
T a[N];
- a的类型是T *
- 可以用a给一个T * 类型的指针赋值
- a是编译时其值就确定了的常量,不能够对a进行赋值
- 作为函数形参时。T *p 和 T p[] 等价
void Func(int *p){ printf("%d",sizeof(p)); }
/
||
/
void Func(int p[]){ printf("%d",sizeof(p)); }
2. 示例
- 指针的应用
#includeint main() { int a[200]; int *p; p = a; //p指向数组a的起始地址,亦即p指向了a[0] *p = 10; //使得a[0]=10 *(p + 1) = 20; //使得a[1]=20 p[0] = 30; // p[i]和*(p+i)是等效的,使得a[0]=30 p[4] = 40; //使得a[4]=40 for(int i=0;i<10;++i) //对数组a的前10个元素进行赋值 *(p + i) = i; ++p; //p指向a[1] printf("%dn",p[0]); //输出1,p[0]等效于*p,p[0]即是a[1] p = a + 6; //p指向a[6] printf("%dn",*p); //输出6 return 0; }
- 颠倒数组
#include参考资料void Reverse(int *p,int size) //颠倒一个数组 { for(int i=0;i int tmp = p[i]; p[i] = p[size-1-i]; p[size-1-i] = tmp; } } int main() { int a[5] = {1,2,3,4,5}; Reverse(a,sizeof(a)/sizeof(int)); for(int i=0;i<5;++i) printf("%d,",*(a+i)); //输出5,4,3,2,1, return 0; }
程序设计与算法(一)C语言程序设计 郭炜 ↩︎
指针的百度百科 ↩︎



