目录
1.指针说明
2.函数、数组、指针
3.二维数组
4.函数指针
5.指针数组
6.指针函数
注意:野指针指没有指明指针内保存的地址。不允许:因为会自由分配一个地址,对其操作很危险。
指针的变与不变:指针变量是变化的,但指针变量指向的地址和值是不变的。
指针=地址 &取地址 *取值
#include <stdio.h>int main(viod)
{int a=10;int *p=&a; //指针=地址 p为地址变量 &取地址 *取值 char *c=&a; //c为地址变量 printf("int中a的地址是%p",p);printf("n char中a的地址是%p",c); printf("n int中a的地址是%p",++p); //自加后不同 printf("n char中a的地址是%p",++c); return 0;
}
作业:输出a,b,c三个数按照顺序输出,函数封装
#include <stdio.h>
void rank(int *a,int *b,int *c);int main(viod)
{int a,b,c;int *d,*e,*f;puts("请输入3个数");scanf("%d%d%d",&a,&b,&c);rank(&a,&b,&c);printf("排序后的三个数为%d,%d,%d",a,b,c);return 0;
} void rank(int *a,int *b,int *c)
{int tmp;int i,j;int first,second,third;if(*a>*b && *a>*c ){first=*a;if(*b>*c){second=*b;third=*c;}else{second=*c;third=*b;}}if(*b>*a && *b>*c ){first=*b;if(*a>*c){second=*a;third=*c;}else{second=*c;third=*a;}} if(*c>*b && *c>*a ){first=*c;if(*a>*b){second=*a;third=*b;}else{second=*b;third=*a;}}*a=first;*b=second;*c=third; }
int a[10]={1,2,3,4,..}
int *p;
p=a; 两个是一样的 p=&a[0];
指针增量和数组的关系
见怪不怪:
1.指针可以用下标法访问内容。
2.数组用*取内容偏移访问 *a++ //先取a指针中的值再进行地址偏移
函数传递传递数组传递的是数组的地址
#include <stdio.h>
void input(int array[],int len);
void output(int array[],int len);
int main(viod)
{int array[3];int len;len=sizeof(array)/sizeof(array[0]);input(&array[0],len); //可以是 input(array,len);output(&array[0],len);return 0;
} void input(int array[],int len)
{int i;for(i=0;i<len;i++){printf("数组的第%d个元素是",i+1);scanf("%d",&array[i]);}
}void output(int *a,int len) // 可以是void output(int array[],int len)
{int i;for(i=0;i<len;i++){printf("数组的第%d个元素是%d",i+1,a[i]); // printf("数组的第%d个元素是%d",i+1,array[i]) } //这里用指针的下标法访问值
}
二维数组 a[3][4]={{1,2,3,4},{4,5,6,7},{7,8,9,10}}
数组名代表元素的首地址: a为二维数组的首地址= &a[0] a[0]=&a[0][0]
a位父数组首地址,a[0]为子数组首地址,*a表示子数组首地址(因为a的父数组中存放的都是子数组的地址,取值就是取地址)
a的偏移a+1是 父数组的偏移,a[0]的偏移a[0]+1 是子数组中数的偏移
a[0]+1 表示0行子数组首地址+1 =*(a+0)+1 表示为第0行的第0个元素
第0行的第一个元素的地址表示为a[0][0]
数组只能初始化的时候一起赋值、否则只能单个赋值
#include <stdio.h>int main(viod)
{int a[3][4]={{1,2,3,4},{4,5,6,7},{7,8,9,10}};int i,j;for(i=0;i<3;i++){for(j=0;j<4;j++){printf("add:0x%p,值是%d n",a[i]+j,*(a[i]+j)); %子数组数组名代表元素的首地址printf("add:0x%p,值是%d n",&(a[i][j]),a[i][j]); %直接取用printf("add:0x%p,值是%d n",*(a+i)+j,*(*(a+i)+j)); %父数组数组名代表元素的首地址printf("---------------------------------------n");}} return 0;
}
函数指针就是函数名的地址,就是要用指针的方式调用函数。
#include <stdio.h>
int num_plus(int num)
{return ++num;
}
int main(viod)
{int (*p)(int num); //定义一个函数指针变量 p是变量名 p=num_plus; //p指向函数 (*p)(10); //函数调用 (*p)相当于取p指针中的值为函数名num_plus printf("调用后的值是%d",(*p)(10));return 0;
}
练习:使用函数指针,a和b两个数,输入1输出大数,输入2输出小数,输入3输出a+b的和。
#include <stdio.h>
int bigger(int a,int b)
{int result;result=a>b?a:b;return result;
} int small(int a,int b)
{int result;result=a<b?a:b;return result;
}
int sum(int a,int b)
{return a+b;
}
int handle(int a,int b,int (*p2)(int a,int b))
{int result;result=p2(a,b);return result;
}int main(viod)
{int a=10,b=20;int cmd;int *p;int (*p2)(int a,int b);int result;printf("指针的大小是%d",sizeof(p)); printf("函数指针的大小是%d",sizeof(p2));printf("请输出命令值:n");scanf("%d",&cmd);switch(cmd){case 1:p2=bigger;break;case 2:p2=small;break;case 3:p2=sum;break;default:printf("输入错误。");break; }result=handle(a,b,p2);printf("结果是%d",result);return 0;
}
是指数值的地址
二位数组 array[2][3]={{1,2,3},{7,8,9}};
int (*p)[3] //定义一个指针,其每次p+1为跳跃一个子数组。
其中p=array,都是指向每次跨越3个值的指针
int *p[4] 数组里每一个内容是一个指针。
由于[]的优先级比*高,所以p先于[4]结合组成数组,然后p再与*结合,表示数组里存放的是一个指向整数的指针变量。
#include <stdio.h>
int main(void){int a=10,b=20,c=30;int *p[3]={&a,&b,&c};int i;for(i=0;i<3;i++){printf("内容是%d n",*(p[i]));} return 0;
}
练习:使用函数指针数组,a和b两个数,输入1输出大数,输入2输出小数,输入3输出a+b的和。
#include <stdio.h>
int bigger(int a,int b)
{int result;result=a>b?a:b;return result;
} int small(int a,int b)
{int result;result=a<b?a:b;return result;
}
int sum(int a,int b)
{return a+b;
} int main(void)
{int a=10,b=20;int (*p2[3])(int a,int b)={bigger,small,sum}; //定义了一个函数指针数组 并且初始化 int result;int i;for(i=0;i<3;i++){printf("result=%d n",(*p2[i])(a,b));}return 0;
}
返回值为指针的函数
int *a(int x,int y); a是函数名。x,y为 函数a的形参,a与()的优先级更高,所以这是一个函数,在函数前面有一个*,表示是函数的返回值是一个指向整型数的指针。
练习:有a个学生b门成绩,要求输出学生序号,打印其所有成绩。
#include <stdio.h>
int *score(int all[][4],int rank){int *p;p=all[rank]; //p=all+rankreturn p;
}int main(void)
{int rank;int all[3][4]={{10,20,30,40},{40,50,60,70},{60,70,80,90}};int *p;printf("请输出要查询学生的序号0 1或2"); scanf("%d",&rank);p=score(all,rank) ;printf("你查询学生的成绩为%d %d %d %d",*p,*(p+1),*(p+2),*(p+3));return 0;
}
**p可以用于存放指针的指针,能直接访问到数据。*(*p))不行需要**p
#include <stdio.h>int main(viod)
{int data=100;int *p=&data;printf("data的地址是%p存放在p里 n",p) ;printf("data的值是%d存放在p里 n",*p) ;//int *p2=&p; 这种定义方式无法访问到data的值 //printf("指针p的地址是%p n",p2) ; //printf("指针p的地址是%p n",*p2) ; int **p2=&p;printf("p的地址是%p存放在二级指针p2里 n",p2) ;printf("data的地址是%p存放在一级指针*p2里 n",*p2) ; printf("data的值是%d存放在**指针p2里 n",**p2) ;return 0;
}
二维数组中父数组虽然保存的是指针,但是其不是一个二级指针,不能定义int **p; p=array;
#include <stdio.h>int main(viod)
{int array[3][4]={{1,2,3,4},{5,6,7,8},{9,2,3,4}};int **prr;prr=array;printf("ppr中存放的地址是:%p n",prr);printf("array的地址是:%p n",array);printf("array中存放的子数组的地址*prr为:%p n",*prr); //所以不能定义为二级指针 printf("array中存放的子数组的地址*array为:%p n",*array);int (*p)[4]=array;prr=&p; //这样定义一个二级指针可以 //**p=100; printf("array中存放的子数组的地址*prr为:%p n",*prr); printf("array中存放的子数组的地址*array为:%p n",*array);return 0;
}
本文发布于:2024-01-28 10:17:58,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/17064082846719.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |