指针相关知识(指针知识点总结)
指针总结
基础概念
系统给虚拟内存的每个存储单元分配了一个编号 ,0x0000 0000-0xff ff ff ff,这个编号是地址 ,指针就是地址
内存数据的访问方式:
(1)直接访问—按变量名存取变量 。
(2)间接访问——将变量的地址存放在另一个变量(指针变量),通过指针变量来访问 。
数据在内存中的地址也称为指针 ,如果一个变量存储了一份数据的指针 ,我们就称它为指针变量 。
在C语言中 ,允许用一个变量来存放指针 ,这种变量称为指针变量 。指针变量的值就是某份数据的地址 ,这样的一份数据可以是数组 、字符串 、函数 ,也可以是另外的一个普通变量或指针变量 。
在32位平台 ,地址总线是32位 ,地址是32位编号 ,所以指针变量是32位即4个字节
注意: (1)无论什么类型的地址,都是存储单元的编号 ,在32位平台下都是4个字节 即任何类型的指针变量都是4个字节大小.在64位系统中任何类型的指针都是8个字节大小 。 (2)对应类型的指针变量 ,只能存放对应类型的变量的地址 举例:整型的指针变量,只能存放整型变量的地址 拓展: 字符变量char ch=’b’;ch占一个字节 ,它有一个地址编号 ,而这个编号就是ch的地址 整型变量int a=0x12345678;a占4个字节,它占4个字节的存储单元 ,有4个地址编号指针的定义及赋值方法
指针变量同普通变量一样 ,使用之前不仅要定义说明 ,而且必须赋予具体的值 。未经赋值的指针变量不能使用 , 否则将造成系统混乱 ,甚至死机 。指针变量的赋值只能赋予地址 , 决不能赋予任何其它数据 ,否则将引起错误 。
1.简单的指针变量 数据类型 * 指针变量名; int * p;//定义了一个指针变量p 注意:在定义指针变量的时候 * 是用来修饰变量的 ,说明变量p是个指针变量。 变量名是p 2.关于指针的运算符 &取地址、*取值(解引用)int pa = &a; 也可以写成 int pa = &a; 即 * 号可以紧跟在变量类型后 ,也可以紧跟在变量名字前,就是个指针类型标识符 。这条语句等价于 int *pa; pa=&a;
其具体含义为:定义一个可以指向整型数据的指针变量pa ,并用整型变量a的地址值对指针变量pa进行初始化 ,从而使指针变量pa具体地指向了整型变量a 。 int a=0x12345678; int b; int *p;//在定义指针变量的时候*代表修饰的意思,修饰p是个指针变量 p=&a;//把a的地址给p赋值 &是取地址符 b=*p;//这里的*是解引用 ,取指针p所指向的变量a的值p保存了a的地址 ,也可以说p指向了a
p和a的关系分析:
a的值是0x12345678,假设a的地址是:0xbf e8 98 68int num;
num=*p; 分析:(1)在调用的时候*代表取值的意思 ,*p就相当于p指向的变量a (2)即num=*p和num=a是等价的 (3)所以num=0x12345678; 小拓展:如果在一行中定义多个指针变量 ,每个指针变量前面都需要加*来修饰 int *p,*q;//定义了两个整型的指针变量p和q int *p,q;//定义了一个整型指针变量p,和整型变量q指针变量的运算(引用)
指针变量可以进行某些运算 ,但其运算的种类是有限的。 它只能进行赋值运算和部分算术运算及关系运算 。
1指针运算符 指针运算符 (1)取地址运算符 & &是单目运算符 ,其结合性为自右至左 ,其功能是取变量的地址 。例&a即变量a的地址 (2)取内容运算符 * *是单目运算符 ,其结合性为自右至左 ,用来表示指针变量所指的变量。在*运算符之后跟的变量必须是指针变量 。 注意:指针运算符*和指针变量说明中的指针说明符* 不是一回事 。 在指针变量说明中 ,“* ”是类型说明符 ,表示其后的变量是指针类型 。int *p; 而表达式中出现的“* ”则是一个运算符用以表示指针变量所指的变量 。*p=&a 若有定义: int a, p=&a (1)&*p 表示:p (2)*&a 表示: a (3)(*p)++相当于a++ (4)*p++相当于*(p++),即先取p所指向变量的值 ,然后 ,让p指向下一个存储单元 。 (5)*++p相当于*(++p),即先让p指向下一个存储单元 ,然后再取p所指向变量的值 。 //利用指针输入变量的值 main() { int a,b; int *p; p=&a; scanf("%d",p); p=&b; scanf("%d",p); printf(”a=%d, b=%d\n",a,b); } 2指针变量的赋值运算 指针变量的赋值运算有以下几种形式: 1.指针变量初始化赋值 ,前面已作介绍 。 2.把一个变量的地址赋予指向相同数据类型的指针变量 。 例如: int a,*pa; pa=&a; /*把整型变量a的地址赋予整型指针变量pa*/ 3.把一个指针变量的值赋予指向相同类型变量的另一个指针变量 。 如: int a,*pa=&a,*pb; pb=pa; 把a的地址赋予指针变量pb, 由于pa,pb均为指向整型变量的指针变量 , 因此可以相互赋值 4.把数组的首地址赋予指向数组的指针变量。 例如: int a[5],*pa; pa=a; (C语言规定数组名表示数组的首地址) 也可写为: pa=&a[0]; 数组第一个元素的地址也是整个数组的首地址 ,也可赋予pa 当然也可采取初始化赋值的方法: int a[5],*pa=a; 5.把字符串的首地址赋予指向字符类型的指针变量 。 例如: char *pc; pc="C language"; 或用初始化赋值的方法写为: char *pc="C Language"; 这里应说明的是并不是把整个字符串装入指针变量 , 而是把存放该字符串的字符数组的首地址装入指针变量 。 注意:指针变量可以赋予0值 ,则p=0表明p是空指针 ,它不指向任何变量;字符串的地址和指向字符串的指针变量
字符串在内存中的起始地址称为字符串的地址 ,可以定义一个字符指针变量指向一个字符串。
1.逐个引用 main() { char *string= ”I love Beijing. ”; for(; *string!=’\0’; string++) printf(“%c ”, *string); printf(“\n ”); } 字符指针变量string中 ,仅存储串常量的地址 ,而串常量的内容(即字符串本身) ,是存储在由系统自动开辟的内存块中,并在串尾添加一个结束标志’\0’ 。 2.整体引用 main() { char *string= ”I love Beijing. ”; printf(“%s\n ”,string); } 通过指向字符串的指针变量string ,整体引用它所指向的字符串的原理:系统首先输出string指向的第一个字符 ,然后使string自动加1,使之指向下一个字符;重复上述过程 ,直至遇到字符串结束标志 。 3.字符指针变量与字符数组之比较 虽然用字符指针变量和字符数组都能实现字符串的存储和处理 ,但二者是有区别的,不能混为一谈。 (1)存储内容不同 。 字符指针变量中存储的是字符串的首地址 ,而字符数组中存储的是字符串本身(数组的每个元素存放一个字符) 。 (2)赋值方式不同 对字符指针变量 ,可采用下面的赋值语句赋值: char *pointer; pointer="This is a example."; 而字符数组 ,虽然可以在定义时初始化 ,但不能用赋值语句整体赋值 。下面的用法是非法的: char array[20]; char array="This is a example."; /*非法用法*/ !!!补:字符数组的正确赋值方法 1 、定义的时候直接用字符串初始化 char a[10]="hello"; 注意:不能先定义再给它赋值 ,如char a[10]; a[10]="hello";这样是错误的!只有定义初始化是才能这样赋值 2 、对数组中字符逐个赋值 char a[10]={h,e,l,l,o}; 3 、利用strcpy ,这个比较值得推荐的方法 char a[10]; strcpy(a, "hello"); (3)指针变量的值是可以改变的 ,字符指针变量也不例外;而数组名代表数组的起始地址 ,是一个常量 ,而常量是不能被改变的 。函数与指针
•用指针变量可以指向一个函数 。简称函数指针 。
•函数在编译时被分配给一个入口地址 。这个函数的入口地址就称为函数的指针。
定义格式:函数的返回值类型(函数指针名)(函数的形参列表)
例:int (p)(int a,int b); //函数的指针 int max(int x,int y)//max函数:判断两个值的最大值 { int z; if(x>y)z=x; else z=y; return(z); } void main() { int max(int ,int); int (*p)();//int (*p)()为函数指针的定义 int a ,b,c; p=max;//将max函数赋给指针函数p scanf(″%d ,%d″ ,&a,&b); c=(*p)(a ,b);//此时*p起到了max函数相同的作用 printf(″a=%d ,b=%d ,max=% d″ ,a ,b ,c); }指针函数:是一个函数 ,但是这个函数的返回值类型是另一个指针 。
int *fun() { int a=10; int *p=10; return p; //return &a;这样写是错的 ,指针函数需要返回一 个指针 ,例如上面的*p才是正确的返回类型 } int main() { int *q=fun(); printf("%d\n",*q); } //例:使用函数指针得出两个数的最大值,最小值 ,相加值。 #include<stdio.h> void main() {//函数声明 int max(int,int); int min(int,int); int add(int,int); void process(int,int,int(*fun)(int,int)); int a,b; printf("enter a and b:"); scanf("%d,%d",&a,&b); printf("max="); process(a,b,max); printf("min="); process(a,b,min); printf("sum="); process(a,b,add); } int max(int x,int y) { int z; if(x>y) z=x; else z=y; return(z); } int min(int x,int y) { int z; if(x<y) z=x; else z=y; return(z); } int add(int x,int y) { int z; z=x+y; return(z); } void process(int x,int y,int(*fun)(int,int)) { int result; result=(*fun)(x,y); printf("%d\n",result); } //这里的fun函数就是一个函数指针 ,可以在main函数中将max,min ,add函数带入使用 。数组与指针
一个数组 ,若其元素均为指针类型数据,称为指针数组
,也就是说 ,指针数组中的每一个元素都相当于一个指针变量 。
一维指针数组的定义形式为:
类型名 数组名[数组长度]; 例如:int *p[4]; //将若干字符串按字母顺序(由小到大)输出。 #include <stdio.h> #include <string.h> void main() { void sort(char *name[],int n); void print(char *name[],int n); //指针数组定义与赋值 char *name[]={"Follow me","BASIC","Great Wall","FORTRAN","Computer design"}; int n=5; sort(name,n); print(name,n); } void sort(char *name[],int n) {//比较首字母顺序 char *temp;//字符串指针变量 int i,j,k; for(i=0;i<n-1;i++) { k=i; for(j=i+1;j<n;j++) if(strcmp(name[k],name[j])>0) { k=j; } if(k!=i) { temp=name[i]; name[i]=name[k]; name[k]=temp; } } } void print(char *name[ ],int n) {//字符串的输出 int i; for(i=0;i<n;i++) printf("%s\n",name[i]); }小结
有关指针的数据类型的小结
定义 含义 int i; 定义整型变量i int *p; p为指向整型数据的指针变量 int a[n]; 定义整型数组a ,它有n个元素 *int p[n]; 定义指针数组p ,它由n个指向整型数据的指针元素组成 int (*p)[n]; p为指向含n个元素的一维数组的指针变量 int f(); f为带回整型函数值的函数 *int p(); p为带回一个指针的函数 ,该指针指向整型数据 int(*p)(); p为指向函数的指针 ,该函数返回一个整型值 int **p; p是一个指针变量 ,它指向一个指向整型数据的指针变量指针运算小结
(1) 指针变量加(减)一个整数 例如:p++ 、P-- 、p+i 、p-i 、p+=i 、p-=i等 。
(2) 指针变量赋值
将一个变量地址赋给一个指针变量 。如:
p=&a(将变量a的地址赋给p)
p=array;(将数组array首元素地址赋给p)
p=&array[ i ];(将数组array第i个元素的地址赋给p)
p=max;(max为已定义的函数 ,将max的入口地址赋给p)
p1=p2;(p1和p2都是指针变量 ,将p2的值赋给p1)(3) 指针变量可以有空值,即该指针变量不指向任何变量。
(4) 两个指针变量可以相减 如果两个指针变量都指向同一个数组中的元素 ,则两个指针变量值之差是两个指针之间的元素个数 。
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!