二维字符数组
对于处理多个一维字符数组不方便时,可以引用二维字符数组,从该角度来说,二维字符数组就是一维字符数组
定义格式
char 数组名[常量1][常量2]
常量1:表示的是定义的字符串的个数
常量2:表示的是每个字符串的最大长度+1
初始化方式
1、单字符初始化:该方式跟二维整形数组一致
2、字符串初始化: 全部初始化:char arr[3][8] = {"apple", "banana", "orange"};
arr[0] arr[1] arr[2]
特殊初始化:char arr[][8] = {"apple", "banana", "orange"}; //此时省略的第一维,会根据初始化字符串的个数确定
部分初始化:char arr[5][8] = {"apple", "banana", "orange"}; //没有初始化的字符串 默认为空串
二维数组元素的使用
1、单字符使用:数组名[行标][列表]---->找到了指定位置上的某个字符
2、字符串使用:数组[行标]----->找到了制定行的一个字符串
二维数组的操作:输入输出、求最值、排序
#include <stdio.h>
#include <string.h>
#define MAX 5
int main()
{
char arr[MAX][20] = {""};//初始化
//二维字符串输入
for (int i = 0; i < MAX; i++)
{
printf("输入字符串%d:\n",i+1);
scanf("%s",arr[i]);
getchar();
}
//输出
printf("目前的二维字符串为:");
for (int i = 0; i < MAX; i++)
{
printf("%s\t",arr[i]);
}
putchar(10);
//取最大
char max[20] = "";
strcpy(max,arr[0]);
for (int i = 0; i < MAX; i++)
{
if(strcmp(max,arr[i])<0)//比较
{
strcpy(max,arr[i]);// 更新最值
}
}
printf("最大的字符串为:%s\n",max);
//字符串升序排序 冒泡排序
char temp[20] = "";//用于交换的变量
for (int i = 1; i < MAX; i++)
{
for (int j = 0; j < MAX-i; j++)
{
if (strcmp(arr[j],arr[j+1])>0)
{
//更新最值
strcpy(temp,arr[j]);
strcpy(arr[j],arr[j+1]);
strcpy(arr[j+1],temp);
}
}
}
printf("重新排序后的二维字符串:");
for (int i = 0; i < MAX; i++)
{
printf("%s\t",arr[i]);
}
putchar(10);
return 0;
}
函数
执行特定功能的代码块
概述
1、系统会提供一些库函数,但是提供的函数有限,如果需要特别定制的函数,需要自己封装
2、对于一些重复调用的语句块而言,如果不进行封装,会使得代码冗余
3、为了提高编程效率,引入了函数,做到一处修改,处处修改
4、目前接触的函数:printf scanf putchar getchar puts gets strapy strcmp strcat strlen
定义
1、函数:执行特点功能的一段代码块
2、定义格式:返回值类型 函数名(参数列表){函数体}
返回值类型:函数执行后,向外界返回的一个结果值,可以有结果(非void),也可以没有结果(void)
定义函数时:有返无返看主调,主调函数想要数据,就定义有返回值函数,主调函数要什么类型的结果,就定义什么数据类型 主调函数不要数据,就定义void类型
函数名:是一个标识符,要符合命名规则
():小括号是函数的标识,即使是没有参数的函数调用时也要将括号加上
参数列表:可以有,也可以没有,表示外界向该函数体提供的数据
定义函数时:有参无参看主调,主调函数给数据,就定义有参函数,主调函数给几个数据,就定义几个参数接收,主调函数给什么类型的数据,就定义什么类型的参数接收 主调函数不给数据,就不定义参数
{}:包裹要封装的代码
函数体代码:要封装的代码
函数分类
1、对于函数定义格式而言,函数名和函数体代码时不可变的,但是,函数的返回值类型和函数的参数时可变的
2、对于一个函数而言,返回值、参数都是可有可无的,由此可将函数分为四大类
1、无参无返回值函数:该函数,仅仅只是单纯执行特定的代码,没有数据传入,也不需要返回结果,仅仅只是执行一个过程
函数定义格式: void 函数名(void) {}
例如:void print_menu(void);
2、有参无返回值函数:该函数,需要主调函数传入给定的数据后,才能进行执行该功能,但是,执行结束后,没有返回结果
函数定义格式:void 函数名(形参列表) {}
例如:void print_arr(int arr[], int n);
3、无参有返回值函数:该函数无需外界传入数据,直接执行内部语句,并且执行结束后,会向主调函数返回一个确定的数据
函数定义格式:返回值类型 函数名(void){}
例如:int getchar(void);
4、有参有返回值函数:该函数需要外界提供对应的参数,执行函数体代码后,并向主调函数返回一个确定的值
函数定义格式:返回值类型 函数名(参数列表) {}
例如:int strlen(char *src);
相关概念
主调函数:调用别的函数的函数叫做主调函数
被调函数:被别的函数调用的那个函数称为被调函数
形式参数:也称形参,定义函数时,括号里面的参数称为形参
实际参数:也称实参,函数调用时,括号里面的参数称为实参
函数调用
函数名(实参)
#include <stdio.h>
#include <string.h>
//定义 无参 无返回值 函数
void sum1()
{
int num,key;
printf("输入两个数:");
scanf("%d%d",&num,&key);
int sum = num + key;
printf("sum = %d\n",sum);
}
//有参 无返回值
void sum2(int a,int b)
{
int sum = a + b;
printf("sum = %d\n",sum);
}
//无参 有返回值
int sum3()
{
int num,key;
printf("输入两个数:");
scanf("%d%d",&num,&key);
int sum = num + key;
return sum;//return(sum) 返回 sum 的值
}
//有参 有返回值
int sum4(int m,int n)
{
int sum = m + n;
return sum;//return(sum) 返回 sum 的值
}
//菜单函数
void printf_menu()
{
printf("\t\t=====1,wu can wu fhz\n");
printf("\t\t=====2,you can wu fhz\n");
printf("\t\t=====3,wu can you fhz\n");
printf("\t\t=====4,you canyou fhz\n");
printf("\t\t=====0,tuic\n");
}
int main()
{
while (1)
{
//menu
int menu = 0;
printf_menu();//调用菜单函数
printf("输入功能代码\n");
scanf("%d",&menu);
getchar();
switch (menu)
{
case 1:
{
sum1();//调用函数sum1
}
break;
case 2:
{
int num,key;
printf("输入两个数:");
scanf("%d%d",&num,&key);
sum2(num,key);
}
break;
case 3:
{
int sum = sum3();//调用 sum3
printf("%d\n",sum);
}
break;
case 4:
{
int num,key;
printf("输入两个数:");
scanf("%d%d",&num,&key);
int sum = sum4(num,key);
printf("%d\n",sum);
}
break;
case 0:
{
return 0;
}
break;
default:
break;
}
}
return 0;
}
练习
1>定义一个有参无返回值函数,主调函数传入两个整数,被调函数中输出两个整数的最大值
2> 定义无参有返回值函数,被调函数中定义并初始化一个长度为5的整形数组,求出该数组的最大值,传递给主调函数输出
3>定义一个有参有返回值函数,主调函数传入三角形的三条边,被调函数判断为何种三角形,并返回给主调函数
返回值设定:
-1:表示不能构成三角形
0:表示构成普通三角形
1:构成等腰三角形
2:构成等边三角形
#include <stdio.h>
#include <string.h>
//1.
void fanHuiZuiDaZhi(int a,int b)
{
int dade = 0;
if(a>b)
{
dade=a;
}else
{
dade=b;
}
printf("其中最大的值为:%d\n",dade);
}
//2.
int shuZhu()
{
int arr[5]={0};
printf("输入数组元素:\n");
for (int i = 0; i < 5; i++)
{
printf("第%d个:\n",i+1);
scanf("%d",&arr[i]);
}
int MAX = arr[0];
for(int i = 0;i < 5;i++)
{
if (MAX<arr[i])
{
MAX = arr[i];
}
}
return MAX;
}
//3.
int sanJioa(int a,int b,int c)
{
if(!(a+b>c&&a+c>b&&c+b>a))
{
return -1;
}else
{
if(a==b&&b==c)
{
return 2;
}else if(a==b||b==c||a==c)
{
return 1;
}else
{
return 0;
}
}
}
//菜单函数
void printf_menu()
{
printf("\t\t=====1>定义一个有参无返回值函数,主调函数传入两个整数,被调函数中输出两个整数的最大值\n");
printf("\t\t=====2> 定义无参有返回值函数,被调函数中定义并初始化一个长度为5的整形数组,求出该数组的最大值,传递给主调函数输出\n");
printf("\t\t=====3>定义一个有参有返回值函数,主调函数传入三角形的三条边,被调函数判断为何种三角形,并返回给主调函数\n");
printf("\t\t=====0>退出\n");
}
int main()
{
while (1)
{
//menu
int menu = 0;
printf_menu();//调用菜单函数
printf("输入功能代码\n");
scanf("%d",&menu);
getchar();
switch (menu)
{
case 1:
{
int num,key=0;
printf("输入两个数:");
scanf("%d%d",&num,&key);
fanHuiZuiDaZhi(num,key);
}
break;
case 2:
{
int MAX=shuZhu();
printf("该数组中最大值为%d\n",MAX);
}
break;
case 3:
{
int a,b,c=0;
printf("输入三角型的三个边:");
scanf("%d %d %d",&a,&b,&c);
int n = sanJioa(a,b,c);
switch(n)
{
case -1:
{
printf("构不成三角形\n");
}break;
case 0:
{
printf("构成普通三角形\n");
}break;
case 1:
{
printf("构成等腰三角形\n");
}break;
case 2:
{
printf("构成等边三角形\n");
}break;
}
}
break;
case 0:
{
return 0;
}
break;
default:
break;
}
}
return 0;
}
函数与变量的关系
局部变量:
定义在函数内部的变量称为局部变量局部
变量的表现形式:
定义在函数体内的变量函数的形式参数定义在语句块内的变量局部变量的
作用域:
从定义开始,到函数结束(语句块内的变量到语句结束)
注意:
不同作用域下的局部变量可以同名
全局变量:也称全程变量和外部变量,就是定义在函数体外部的变量
作用域:从定义开始到整个程序结束为止,该变量定义后的任意一个函数都可以使用他
注意:局部变量可以跟全局变量同名,函数体内使用的默认是局部变量(就近访问原则,局部优先原则)
如果非要使用全局变量,也不是不可以,需要使用关键字 extern 来声明
静态局部变量:不会随着所在函数的结束而释放空间
数组作为函数参数传递
1、数组的要素:起始地址(数组名),数组的容量
2、数组作为函数参数传递属于地址传递,形参类容的改变,实参类容也会跟着改变
3、定义形参接收数组时,接收数组名时,只需要定义一个变量标识数组即可
作业
完成学生管理系统
1、使用菜单完成
2、有学生的信息录入功能:输入学生个数,并将学生的姓名、分数录入
3、查看学生信息:输出所有学生姓名以及对应的分数
4、求出学习最好的学生信息:求最大值
5、按姓名将所有学生进行升序排序
6、按成绩将学生学生进行升序排序要求每个功能使用函数完成
一、使用全局变量
#include <stdio.h>
#include <string.h>
char name[100][6] ={'\0'};
int chengJi[100] = {0};
int n = 0;
//1,学生信息录入
void lu_ru()
{
printf("姓名录入:\n");
for (int i = 0; i < n; i++)
{
printf("输入第%d个学生的姓名:",i+1);
scanf("%c",name[i]);
getchar();
printf("输入第%d个学生的成绩:",i+1);
scanf("%d",&chengJi[i]);
getchar();
putchar(10);
}
putchar(10);
}
//2.查成绩
void cha()
{
for(int i = 0;i < n;i++)
{
printf("姓名:%s 成绩:%d\n",name[i],chengJi[i]);
}
putchar(10);
}
//3.最好成绩
void zui_hao_cj()
{
int maxi = chengJi[0];
char maxj[10] ={"\0"};
for(int i = 0;i<n;i++)
{
if(maxi<chengJi[i])
{
maxi=chengJi[i];
strcpy(maxj,name[i]);
}
}
printf("成绩最好的学生是%s,成绩为%d\n",maxj,maxi);
}
//4.按名字排序
void mz_pai_xu()
{
for(int i = 1;i < n;i++)
{
for(int j = 0;j<n-i;j++)
{
if(strcmp(name[j],name[j+1])>0)
{
int temp = chengJi[j];//定义中间变量,交换数值
chengJi[j] = chengJi[j+1];
chengJi[j+1] = temp;
char temp2[n];
strcpy(temp2,name[j]);
strcpy(name[j],name[j+1]);
strcpy(name[j+1],temp2);
}
}
}
printf("重新排序后的结果为:\n");
for(int i = 0;i < n;i++)
{
printf("姓名:%s 成绩:%d\n",name[i],chengJi[i]);
}
}
//5.按成绩排序
void cj_pai_xu()
{
for(int i = 1;i < n;i++)
{
for(int j = 0;j<n-i;j++)
{
if(chengJi[j]>chengJi[j+1])
{
int temp = chengJi[j];//定义中间变量,交换数值
chengJi[j] = chengJi[j+1];
chengJi[j+1] = temp;
char temp2[n];
strcpy(temp2,name[j]);
strcpy(name[j],name[j+1]);
strcpy(name[j+1],temp2);
}
}
}
printf("重新排序后的结果为:\n");
for(int i = 0;i < n;i++)
{
printf("姓名:%s 成绩:%d\n",name[i],chengJi[i]);
}
}
//菜单函数
void printf_menu()
{
printf("\t\t=====1,学生信息录入\n");
printf("\t\t=====2,查看学生信息\n");
printf("\t\t=====3,成绩最好的学生\n");
printf("\t\t=====4,按名字升序排序\n");
printf("\t\t=====5,按成绩升序排序\n");
printf("\t\t=====0,退出\n");
}
int main()
{
while (1)
{
//menu
int menu = 0;
printf_menu();//调用菜单函数
printf("输入功能代码\n");
scanf("%d",&menu);
getchar();
switch (menu)
{
case 1:
{
printf("输入学生个数:");
scanf("%d",&n);
getchar();
lu_ru();
}
break;
case 2:
{
cha();
}
break;
case 3:
{
zui_hao_cj();
}
break;
case 4:
{
mz_pai_xu();
}
break;
case 5:
{
cj_pai_xu();
}
break;
case 0:
{
return 0;
}
break;
default:
break;
}
}
return 0;
}
二、尽量不使用全局变量
#include <stdio.h>
#include <string.h>
//1,学生信息录入
void lu_ru_mz(char name[][6],int n)
{
printf("姓名录入:\n");
for (int i = 0; i < n; i++)
{
printf("输入第%d个学生的姓名:\n",i+1);
scanf("%s",name[i]);
}
putchar(10);
}
void lu_ru_cj(int chengJi[],int n)
{
printf("成绩录入:\n");
for (int i = 0; i < n; i++)
{
printf("输入第%d个学生的成绩:\n",i+1);
scanf("%d",&chengJi[i]);
}
putchar(10);
}
//2.查成绩
void cha_mz(char name[][6],int n)
{
for(int i = 0;i < n;i++)
{
printf("姓名:%s \n",name[i]);
}
putchar(10);
}
void cha_cj(int chengJi[],int n)
{
for(int i = 0;i < n;i++)
{
printf("成绩:%d\n",chengJi[i]);
}
putchar(10);
}
//3.最好成绩
int zui_hao_cj(int chengJi[],int n)
{
int maxi = chengJi[0];
for(int i = 0;i<n;i++)
{
if(maxi<chengJi[i])
{
maxi=chengJi[i];
}
}
return maxi;
}
int main()
{
char name[100][6] ={'\0'};
int chengJi[100] = {0};
int n = 0;
printf("输入学生个数:");
scanf("%d",&n);
lu_ru_mz(name,n);
lu_ru_cj(chengJi,n);
cha_mz(name,n);
cha_cj(chengJi,n);
int maxi=zui_hao_cj(chengJi,n);
int j = 0;
for(j = 0;j<n;j++)
{
if(chengJi[j]==maxi)
break;
}
printf("成绩最好的学生是%s,成绩为%d\n",name[j],chengJi[j]);
}