Day10、指针与函数、数组

比较三个数的大小

  1#include<stdio.h>

  2int main(){

 3     intnum=0,num1=0,num2=0,tmp=0;

 4     int*p_num=&num,*p_num1=&num1,*p_num2=&num2;

 5     printf("请输入三个数: ");

 6    scanf("%d%d%d",&num,&num1,&num2);

 7     if(num<num1){

 8         tmp=num;

  9         num=num1;

 10        num1=tmp;

 11     }

 12    if(num<num2){

 13        tmp=num;

 14        num=num1;

 15        num1=tmp;

 16     }

 17    if(num1<num2){

 18        tmp=num1;

 19        num1=num2;

 20        num2=num1;

 21     }

 22     printf("%d%d %d\n",num,num1,num2);

 23    return 0;

24 }

使用指针:

  1 #include<stdio.h>

  2 int main(){

  3     int num=0,num1=0,num2=0,tmp=0;

  4     int*p_num=&num,*p_num1=&num1,*p_num2=&num2,*p_tmp=&tmp;

  5     printf("请输入三个数: ");

  6    scanf("%d%d%d",p_num,p_num1,p_num2);

  7     if(*p_num<*p_num1){

  8         *p_tmp=*p_num;

  9         *p_num=*p_num1;

 10         *p_num1=*p_tmp;

 11     }

 12     if(*p_num<*p_num2){

 13         *p_tmp=*p_num;

 14         *p_num=*p_num1;

 15         *p_num1=*p_tmp;

 16     }

 17     if(*p_num1<*p_num2){

 18         *p_tmp=*p_num1;

 19         *P_num1=*p_num2;

 20         *p_num2=*p_num1;

 21     }

 22     printf("%d %d%d\n",*p_num,*p_num1,*p_num2);

 23     return 0;

24 }

也可以修改指针指的存储区,若num<num1,存储区内容不变,用p_num指针指向存储区内容数大的,用p_num1指向存储区内容数小的

 7     if(*p_num<*p_num1){

 8         p_tmp=p_num;

 9         p_num=p_num1;

 10        p_num1=p_tmp

 11     }

 12    if(*p_num<*p_num2){

 13        p_tmp=p_num;

 14        p_num=p_num2;

 15        p_num2=p_tmp

 16        

 17     }

 18    if(*p_num1<*p_num2){

 19        p_tmp=p_num1;

 20        p_num1=p_num2;

 21        p_num2=p_tmp

 22        

 23     }

指针和变量之间的捆绑关系会随着程序的执行不断变化,可以把指针看做变量的某种身份,利用指针可以针对身份编写程序

当把指针和数组中第一个存储区捆绑好以后,就可以通过这个指针找到数字里的每个存储区,此时可以认为指针间接捆绑了整个数组

可以在这种指针后面使用下标来表示数组里的存储区

  1#include<stdio.h>

  2int main(){

 3     int arr[]={1,2,3,4,5},num=0;

 4     int *p_arr=arr;

 5     for(num=0;num<=4;num++){

 6         printf("%d",arr[num]);

 7         printf("%d ",p_arr[num]);

 8     }

 9     printf("\n");

 10    return 0;

 11 }

地址数据只能参与如下几个计算过程:

地址+整数  地址-整数   地址-地址

地址数据加减整数n实际加减的是n个捆绑存储区的大小

  1#include<stdio.h>

  2int main(){

 3     int arr[]={1,2,3,4,5},num=0;

 4     int *p_arr=arr;

 5     printf("arr是%p\n",arr);

 6     printf("arr+3是%p\n",arr+3);

 7     return 0;

  8} 

地址数据相减结果是一个整数,这个整数表示两个地址之间包含的存储区个数

printf("&arr[3]-arr是%d\n",&arr[3]-arr);      结果是3

数组中第一个存储区的地址加下标可以得到下标对应存储区的地址

 8     printf("*(arr+3)是%d\n",*(arr+3));

 9     printf("*(p_arr+3)是%d",*(p_arr+3));     执行结果一样

所有跨函数使用存储区都是用指针实现的

数组做形式参数的时候,真正的形式参数是一个指针变量

练习:编写函数生成彩票,主函数负责显示彩票内容,用指针

  1#include<stdio.h>

  2#include<stdlib.h>

  3#include<time.h>

  4void creat(int *p_arr,int size)

 5     int *p_tmp=NULL;

 6     for(p_tmp=p_arr;p_tmp<=p_arr+size-1;p_tmp++){

 7         *p_tmp=rand()%36+1;

 8     }

  9 }

 10int main(){

 11    int arr[7]={0};

 12    int *p_tmp=NULL;

 13    srand(time(0));

 14    creat(arr,7);

 15    for(p_tmp=arr;p_tmp<=arr+6;p_tmp++){

 16        printf("%d ",*p_tmp);

 17    }  

 18    return 0;

 19}  

练习:编写函数把主函数里的两个变量的内容做交换

  1#include<stdio.h>

  2void swap(int *p_num,int *p_num1){

 3     int tmp;

 4     tmp=*p_num;

 5     *p_num=*p_num1;

 6     *p_num1=tmp;

  7 }

  8int main(){

 9     int num=1,num1=2;

 10    printf("num=%d,num1=%d\n",num,num1);

 11    swap(&num,&num1);

 12    printf("num=%d,num1=%d\n",num,num1);

 13 }

函数可以提供指针类型存储区记录地址数据返回值,采用这种方法可以让调用函数使用被调用函数的存储区

绝不可以把局部变量的地址作为返回值使用  (因为局部变量的生命周期是被调用函数工作期间,调用结束,归还存储区。所以必须使局部变量是静态的,因为静态局部变量的生命周期是直到整个程序结束)

  1#include<stdio.h>

  2int *read(void){

 3     static int num=0;

 4     printf("请输入一个整数: ");

 5    scanf("%d",&num);

 6     return &num;

  7 }

  8int main(){

 9     int *p_num=read();

 10    printf("%d",*p_num);

 11    return 0;

 12 }

练习:编写函数,找出主函数中数组里最大的数,用指针

  1#include<stdio.h>

  2int *max(int *p_num,int size){

 3     int *p_tmp=NULL,*p_max=NULL;

 4     //永远和处理过的存储区中最大的数字所在的存储区捆绑

 5    for(p_tmp=p_num;p_tmp<=p_num+size-1;p_tmp++){

 6        if(p_max==0||*p_max<*p_tmp){

 7             p_max=p_tmp;

 8         }

 9     }

 10    return p_max;

 11 }

 12int main(){

 13    int arr[]={1,0,3,8,12,13,5};

 14    int *p_num=max(arr,5);

 15    printf("%d\n",*p_num);

 16    return 0;

 17 }

若返回值是地址,定义函数时就需要加*表示指针(地址)类型

int*p_num=max(arr,5);  等同于 int *p_num;  p_num=max(arr,5);


声明指针变量时可以使用const关键字

声明指针变量时可以把const关键字写在类型名称前。作用是不可以通过这种指针对捆绑的存储区赋值,但是可以对指针本身做赋值。 例:

 4     int *p_num=&num;

 5     *p_num=10;     可以

 

  1#include<stdio.h>

  2int main(){

 3     int num=0;

 4     const int *p_num=&num;

 5     // *p_num=10;  错误

 6     p_num=NULL;

 7     return 0;

  8}  

所有用来实现跨函数使用存储区的指针形式参数都尽量采用以上方式加const关键字

(加个记号,告诉调用函数不会改)

也可以在声明变量的时候把const关键字写在指针变量名称前。作用是不可以对这种指针做赋值,但是可以通过这种指针对捆绑的存储区做赋值

  1#include<stdio.h>

  2int main(){

 3     int num=0;

 4     int * const p_num1=&num;

 5     *p_num1=10;

 6     p_num1=NULL;   // 错误

 7     return 0;

  8 }

 

声明指针变量时可以使用void作为类型名称

这种指针可以和任意类型的存储区捆绑,这种指针叫无类型指针

不能通过这种指针知道捆绑存储区的类型

  1#include<stdio.h>

  2int main(){

 3     char ch='o';

 4     int num=10;

 5     float fnum=4.3f;

 6     void *p_v=NULL;

 7     p_v=&ch;

 8     p_v=&num;

 9     p_v=&fnum;

 10    return 0;

 11 }

不能在这种指针前直接使用*操作符,也不能用这种指针直接进行加减整数计算

这种指针必须首先强制类型转换成有类型指针才能使用

  1#include<stdio.h>

  2int main(){

 3     char ch='o';

 4     int num=10;

 5     float fnum=4.3f;

 6     void *p_v=NULL;

 7     p_v=&ch;

 8    printf("%c\n",*(char *)p_v);

 9     p_v=&num;

 10    printf("%d\n",*(int *)p_v);

 11    p_v=&fnum;

 12    printf("%g\n",*(float *)p_v);

 13    return 0;

 14 }

这种指针通常作为函数的形式参数使用,可以通过它把任意类型的存储区传递给调用函数

C语言里规定文字信息必须记录在一组连续的字符类型存储区里

所有文字信息的最后必须使用 ‘\0 ‘ 字符结束,这个字符的ASCII码就是0

我们把符合以上两个特征的内容叫字符串,字符串就可以用来在C语言中记录文字信息

只有 ‘\0’ 前面的内容才被看做是有效字符

所有字符串都可以采用字符类型指针表示

字符串字面值是一种字符串,用双引号中间的一组字符表示,例如“abc”,“^*&”等

编译器在编译的时候会自动在字符串字面值的最后加’\0’字符

编译器在编译时会把字符串字面值替换成第一个字符所在存储区的地址

  1#include<stdio.h>

  2int main(){

 3    printf("%p\n","abc");

 4     printf("%c\n",*"abc");

 5    printf("%d\n",*("abc"+3));

 6     return 0;

  7 }

字符串字面值里的所有字符在程序执行过程中不可以被修改

程序中多个内容一样的字符串字面值在内存里只有一个

 3    printf("%p\n","abc");

 4    printf("%p\n","abc");

结果:

0x8048524

0x8048524

多个并列的字符串字面值会被编译器合并成一个

字符数组也可以用来记录字符串

只有包含 ‘ \0’ 字符的字符数组才能当字符串使用

可以使用字符串字面值对字符数组进行初始化,编译器会把字符串字面值里的’\0’字符初始化到字符数组里

 3     char str[]="abc";

 4     printf("sizeof(str)是%d\n",sizeof(str));     结果为4

字符数组里的字符串可以修改

使用%s做占位符把字符串里的所有字符显示在屏幕上       printf("%s\n","abcdef");

练习:编写函数把一个数组里所有存储区的内容前后颠倒,用指针编写

1 2 3 4 5

5 4 3 2 1

  1#include<stdio.h>

  2void reverse(int *p_num,int size){

 3     int *p_head=p_num;

 4     int *p_tail=p_num+size-1;

 5     int tmp=0;

 6     while(p_head<p_tail){

 7         // 交换配对存储区的内容

 8         tmp=*p_head;

 9         *p_head=*p_tail;

 10        *p_tail=tmp;

 11        p_head++;   // p_head指针向后移动一步

 12        p_tail--;   // p_tail指针向前移动一步

 13     }

 14 }

 15int main(){

 16    int arr[]={1,2,3,4,5};

 17    int i=0;

 18    reverse(arr,5);

 19    for(i=0;i<=4;i++){

 20         printf("%d ",arr[i]);

 21     }

 22    printf("\n");

 23    return 0;

24 }

 

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计,皆可应用在项目、毕业设计、课程设计、期末/期/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值