当前位置: 首页 > news >正文

第13天小整理

1.有关字符串的问题分析

#include <stdio.h>
#include <string.h>
int main(){int b=0;char a[5]={0};gets(a);b=strlen(a);printf("%d\n",b);return 0;
}

在此处输入10个字符,输出结果将为10,而非5。

这是因为:

  1. gets 函数存在严重的安全隐患,因为它不会检查输入的字符串长度是否会超出目标数组的大小,很容易导致缓冲区溢出错误。
  2. strlen 函数会从字符串的起始位置开始,一直计数直到遇到空终止符 '\0'

当gets()产生溢出错误时,可能会得到这样的提示

*** stack smashing detected ***: terminated

 2.使用字符串进行格式化输出

int main(){int a=5;char *str="%d\n";printf(str,a);return 0;
}

这里首先定义了一个字符指针 str,并将其初始化为字符串 "%d\n"

调用 printf 函数,将字符指针 str 所指向的格式控制字符串作为第一个参数传入,将整型变量 a 作为第二个参数传入。这样做的效果等同于直接写 printf("%d\n", a);,也就是会将变量 a 的值以十进制整数的形式输出,然后换行。

当程序运行时,会输出:5

3.函数指针调用

(1)直接调用

#include <stdio.h>int fun(void) {// 先定义函数fun,这里函数fun只是简单返回一个值42return 42;
}int main() {int (*p)(void) = fun;    // 定义并初始化函数指针p,让它指向fun函数int result = p();   // 使用函数指针p调用函数funprintf("函数调用结果: %d\n", result);return 0;
}//42

我们通过函数指针 p 调用了函数 fun。这里 p() 的作用就和之前直接写 fun() 是一样的,都是去执行函数 fun 里面的代码逻辑,然后函数 fun 会返回一个值(在这里它返回 42),这个返回值就被存储在了变量 result 里,后面我们就可以用这个 result 做其他的事情啦

(2)作为函数参数传递调用方式

#include <stdio.h>int fun(void) {// 同样先定义函数fun,返回值为42return 42;
}void newFun(int (*func)(void)) {// 定义一个新的函数newFun,它接受一个函数指针作为参数int result = func();printf("在新函数中调用结果: %d\n", result);
}int main() {int (*p)(void) = fun;// 定义并初始化函数指针p指向fun函数newFun(p);// 把函数指针p传递给新函数return 0;
}

首先我们还是有函数 fun 和让函数指针 p 指向它的操作。

然后我们定义了一个新的函数newFun,这个函数的参数是一个函数指针 func,它要求这个函数指针指向的函数是不接受任何参数且返回值类型为 int 的函数(和我们前面定义的函数指针 p 以及函数 fun 的特性是匹配的)。

在主函数里,我们通过  newFun(p)把函数指针 p 传递给了 newFun函数。

到了 newFun 函数里面,通过 int result = func(); 这一行,就用接收到的函数指针 func(其实这里的 func 就是我们传进去的 p)去调用了函数 fun,然后把调用得到的结果输出显示出来了。

🤫最后,是一个关于对数组进行增删改查操作的函数封装小练习

//数组的增删改查功能集合 
#include <stdio.h>
#include <string.h>
int flag=0;
void add(int a[]);
void search(int a[]);
void change(int a[]);
void dele(int a[]);
void list(int a[]);
int main(){int a[50]={0},i;char val=0,temp=0;while(1){printf("------------------------------------------------\n");printf("0.退出\n1.增加数据\n"); printf("2.查找数据\n3.更改数据\n"); printf("4.删除数据\n5.查看当前数据\n"); 		printf("------------------------------------------------\n");scanf("%c",&val);printf("\n");while(getchar()!='\n');//清空缓冲区 switch(val){case '0':return 0;break;case '1':add(a);break;case '2':search(a);break;case '3':change( a);break;case '4':dele(a);break;case '5':list(a);break;default:printf("there is not this\n");break;}}return 0;
}	
void list(int a[50]){int i;printf("现在我们有:");for(i=0;i<50;i++){if(a[i]!=0){printf("%d、",a[i]);}}printf("\n");
} 
void add(int a[50]){int n=0,i;char y=0;for(i=0;i<50 && a[i]!=0;i++){n++;}printf("请输入想添加的数据\n");for(i=n;i<50;i++){scanf("%d",&a[i]);while(getchar()!='\n');//清空缓冲区 printf("添加成功\n");printf("是否输入完毕?y or n \n");scanf("%c",&y);while(getchar()!='\n');//清空缓冲区 if(y=='y'){break;} else{printf("请输入想添加的数据\n");	}}	 printf("现在我们有:");for (i = 0; i < 50; i++) {if (a[i]!= 0) {printf("%d、", a[i]);}}printf("\n");
}void search(int a[50]){int sear=0,i,found=0;  printf("请输入想查询的数据\n");scanf("%d",&sear);while(getchar()!='\n');//清空缓冲区 for(i=0;i<50;i++){if(a[i]==sear){printf("是第%d个\n",i+1);found++;}}if(found==0){printf("这儿没有这数\n");}
}
void change(int a[50]){int chan=0,chang=0,i;printf("现在我们有:");for(i=0;(a[i]!=0)&&(a[i+1]!=0);i++){printf("%d、",a[i]);}printf("\n");printf("请输入想修改的数据\n");scanf("%d",&chan);while(getchar()!='\n');//清空缓冲区 for(i=0;i<50;i++){if(a[i]==chan){printf("要改成什么:");scanf("%d",&chang);while(getchar()!='\n');a[i]=chang; }}printf("修改完成!\n");}void dele(int a[50]){int delet=0,i,j;printf("现在我们有:");for(i=0;i<50;i++){if(a[i]!=0){printf("%d、",a[i]);}}printf("\n");printf("请输入想删除的数据\n");scanf("%d",&delet);while(getchar()!='\n');//清空缓冲区 for(i=0;i<50;i++){if(a[i]==delet){flag++;for (j = i; j < 49; j++) {a[j] = a[j + 1];}a[49] = 0;i--;  // 因为数组元素向前移动了,所以要重新检查当前位置}}if(flag==0){printf("这儿没有这个数\n");}else {printf("删除成功\n");	}}

以及2.0版本

//新增:插入功能和排序功能
#include <stdio.h>
int s[50]={0};//定义数据数组 
int n=0;
int VAL[50]={0};//定义下标数组 char menu(void);//菜单函数声明 
void ADD(void);//添加函数声明
void PRINT(void);//输出函数声明
int FIND(void);//查询函数声明
void CHANGE(void);//修改函数声明
void DELETE(void);//删除函数声明
void INSERT(void);//插入函数声明
void SEQUENCE(void);//排序函数声明
int main()
{char ret=0;//定义获取返回值结果变量 while(1){ret = menu();//选项为菜单函数返回值 switch(ret){case '0':return 0;break;case '1':ADD();break;case '2':PRINT();break;case '3':FIND();break;case '4':CHANGE();break;case '5':DELETE();break;case '6':INSERT();break;case '7':SEQUENCE();break;default :printf("error!\n");}}return 0;
}char menu(void)
{char val=0;//定义选择项 printf("0.退出 1.新增 2.打印 3.查询 4.修改 5.删除 6.插入 7.排序\n");scanf("%c",&val);while(getchar()!='\n');return val;
}void ADD(void)
{if(n>=50)//判断数据数组是否存满 {printf("存储已满!\n");return ;}printf("新增数据:");scanf("%d",&s[n]);//输入新数据 while(getchar()!='\n');n++;//数据个数自增 
}void PRINT(void)
{for(int i=0;i<n;i++){//遍历输出数据 printf("%d ",s[i]);}printf("\n");
}int FIND(void)
{int tmp=0; int VALN=0;//定义下标数组个数位 printf("查询的数据:");scanf("%d",&tmp);//输入查询数据 while(getchar()!='\n');for(int i=0;i<n;i++){if(tmp==s[i])//遍历判断是否与查询数据相同 {printf("下标:%d\n",i); //输出相等的数据的下标 VAL[VALN]=100+i;//将其下标计入下标数组VAL的VALN位 VALN++;//个数位自增 }}if(VALN==0)//如果个数位未变,则数据不存在 {printf("数据不存在!\n");}return VALN;//返回相同数据的个数 
}void CHANGE(void)
{int ret = FIND();//获取相同数据的个数 if(ret == 0){return ;}若无相同个数,直接返回 for(int i=0;i<ret;i++){//遍历下标数组,输出数据数组中对应的值 printf("新值:");scanf("%d",&s[VAL[i]-100]);while(getchar()!='\n');}	printf("修改完成!\n");	
}void DELETE(void)
{int ret = FIND();//获取相同数据的个数 if(ret == 0){//若无相同个数,直接返回 return ;}for(int i=ret-1;i>=0;i--){//依次向前遍历下标数组的每个下标值 for(int j=VAL[i]-100;j<n-1;j++){//j获取到下标值后,将对应下标值后数据前移,覆盖应删除数据。 s[j]=s[j+1];}n--;//每经过依次删除循环,数据个数自减1 }printf("删除完成!\n");
}
void INSERT(void){printf("想插入到哪个数据之前\n");int ret = FIND();//获取相同数据的个数 if(ret == 0){//若无相同个数,直接返回 return ;}for(int i=0;i<ret;i++){for(int j=n-1;j>=(VAL[i]-100);j--){s[j+1]=s[j];}printf("请输入插入值:"); scanf("%d",&s[VAL[i]-100]);while(getchar()!='\n');n++;}printf("插入成功!\n");
}
void SEQUENCE(void){int tmp=0;char op;printf("请选择如何排序?A.从小到大 B.从大到小\n");scanf("%c",&op);while(getchar()!='\n');if(op=='A'){printf("将数据从小到大排序:");for(int i=1;i<n;i++){for(int j=0;j<n-i;j++){if(s[j]>s[j+1]){tmp=s[j];s[j]=s[j+1];s[j+1]=tmp;}} }return PRINT();		}else{printf("将数据从大到小排序:");for(int i=1;i<n;i++){for(int j=0;j<n-i;j++){if(s[j]<s[j+1]){tmp=s[j];s[j]=s[j+1];s[j+1]=tmp;}} }return PRINT();	}
}


http://www.mrgr.cn/news/60579.html

相关文章:

  • Vue 前端面试通关秘籍:响应式、组件化、数据绑定等核心要点一网打尽
  • 华为配置 之 IPv6路由配置
  • 安卓基础001
  • hmc7044时钟芯片调试笔记
  • 什么是AI神经网络?
  • nacos的原理,为什么可以作为注册中心,和zookeeper的区别
  • 机器学习入门之监督学习
  • 并联 高电压、高电流 放大器实现 2 倍输出电流模块±2A
  • 《学会提问》
  • qt-opensource-windows-x86-5.14.2.rar
  • 聚水潭到畅捷通T+的数据高效集成方案解析
  • OceanBase数据库结合ETLCloud快速实现数据集成
  • GEE 图表:利用CGIAR/SRTM90_V4绘制雷尼尔山登山步道沿途的海拔高度图表
  • DevCon,我们来了|DAOBase 线下活动(曼谷站)
  • python -m pip install --upgrade pip和pip install --upgrade pip有什么区别?
  • python读取CSV文件
  • 算法4之链表
  • C++:字符串
  • Unable to add window -- token null is not valid; is your activity running?
  • 【JIT/极态云】技术文档--函数设计
  • 可重入函数和不可重入函数
  • LVGL移植教程(超详细)——基于GD32F303X系列MCU
  • 量子容错计算
  • 【JVM】——GC垃圾回收机制(图解通俗易懂)
  • PowerShell 提示“系统禁止运行脚本”
  • 【嵌入式软件-STM32】按键控制LED 光敏传感器控制蜂鸣器