C语言(第2篇)——指针、数组、函数

阅读: 评论:0

C语言(第2篇)——指针、数组、函数

C语言(第2篇)——指针、数组、函数

目录

1.指针说明

2.函数、数组、指针

3.二维数组

 4.函数指针

5.指针数组

6.指针函数


注意:野指针指没有指明指针内保存的地址。不允许:因为会自由分配一个地址,对其操作很危险。
指针的变与不变:指针变量是变化的,但指针变量指向的地址和值是不变的。

1.指针说明

指针=地址   &取地址  *取值

#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指针中的值再进行地址偏移

2.函数、数组、指针

函数传递传递数组传递的是数组的地址

#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]) } //这里用指针的下标法访问值
}

3.二维数组

二维数组 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; 
} 

4.函数指针

函数指针就是函数名的地址,就是要用指针的方式调用函数。

#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; 
} 

5.数组指针

是指数值的地址

二位数组  array[2][3]={{1,2,3},{7,8,9}};

int (*p)[3]  //定义一个指针,其每次p+1为跳跃一个子数组。

其中p=array,都是指向每次跨越3个值的指针

6.指针数组

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; 
} 

7.指针函数

返回值为指针的函数

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; 
} 

8.二级(多级)指针

**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; 
} 

9.二级指针与二维数组

二维数组中父数组虽然保存的是指针,但是其不是一个二级指针,不能定义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; 
} 

10.各种指针的定义

本文发布于:2024-01-28 10:17:58,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/17064082846719.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:数组   指针   函数   语言
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23