用函数实现模块化程序设计
函数:
按照模块化程序设计,事先编译好常用的函数来实现各种不同的功能。
定义函数:
return_type function_name( parameter list)//函数返回值的类型 函数名(参数的名字和类型)
{
body of the function//函数主体
}
类型为void的函数,意为函数无类型,即无函数值。执行后不会把任何值带回其他函数中。
参数类型为void,函数没有参数。
定义空函数,在准备扩充功能的地方写上一个空函数,只是暂时还没编写好。
调用函数
1.一般形式:function_name(parameter list)
1).把函数调用单独作为一个语句。不要求带回值,只要求有一定功能。
2).出现在另一个表达式中。带回一个确定的值参与表达式运算。
3).作为其他函数的实参。
2.函数调用时的数据传递
1)形式参数和实际参数
在定义函数时使用的为形式参数或虚拟参数;在主调函数中调用一个函数时使用实际参数。
在调用过程中,发生将实参传递给被调用函数形参,的数据传递称为“虚实结合”。
实参可以是常量,变量或表达式。实参与形参的类型应相同或赋值兼容(按照不同类型数值的赋值规则进行转换)。
3.调用的过程
,在函数发生调用时,实参的值传递给对应形参,形参被临时分配内存单元,进行相关的运算,再通过return将函数值带回主调函数中,调用结束,形参单元被释放。
实参向形参的数据传递是“值传递”,单向传递,只能由实参传给形参。
4.函数的返回值
函数的返回值是通过函数中的return语句获得的。
return语句正确表达式为return(参数/表达式)。为参数时省略括号,为表达式时简化函数内容。
要确定返回值的类型。铁则:函数类型决定返回值的类型。
对于不带回值的函数,应当定义函数为“void类型”(空类型)。系统会禁止在调用函数中使用被调用函数的返回值,此时不得出现return语句。
对被调用函数的声明和函数原型
1.所需条件:(1)已被定义的函数;(2)如果使用库函数,应该在文件开头用#include命令调用有关库函数时所需用到的信息“包含”到本文件中。(3)如果是自己定义的函数,该函数的位置在主调函数的后面(同一文件中),应该在主调函数中对被调用的函数做声明。声明的作用是把函数名、函数参数的个数和参数的类型等信息通知编译系统,以便在遇到函数调用时,系统能正确识别函数并检查调用是否合法。
(函数声明比函数定义中的首行多一个分号)实际上,函数声明中的形参名可以省写,而只写形参的类型,编译系统只关心和检查参数个数和参数类型,而不检查参数名,因为在调用函数时只要求保证实参类型与形参类型一致,而不考虑形参名是什么。这样虽然精炼,但有意义的参数名有利于理解程序。
写在所有函数前面的外部声明在整个文件范围中有效。
函数的嵌套调用
在调用一个函数的过程中,有调用另一个函数。
函数的递归调用
在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的递归调用。
用if语句还控制无休止的的递归调用。
简单来说,可以吧递归看作多重嵌套的循环语句。当最里面的循环语句执行结束后,将会往上一层进行回溯。
回溯,为了求得问题的解,选择某一中可能的情况向前探索。在探索过程中,一旦发现原来的选择是错误的,就退回上一步重新选择条件,继续向前探索。
一个递归的问题可以分为“回溯”和“递归”两个阶段。
数组作为函数参数
调用有参函数时,需要提供实参。实参可以是变量,常量或表达式。数组元素的作用与变量相当,一般来说,凡是变量可以出现的地方,都可以用数组元素代替。因此,数组元素也可以用作函数实参,向形参传递数组元素的值。数组名也可以作为实参和形参,传递的是数组第一个元素的地址。
数组元素作函数实参
数组元素可以用作函数实参,但是不能用作形参。因为形参是函数被调用时临时分配储存单元,不可能为一个数组元素单独分配存储单元。数据传递的方向是,从实参传到形参,单向传递。
一维数组名作函数参数
用数组名作函数参数,应该在主调函数和被调韩式分别定义数组。参数的类型应一致。在定义函数时,在实际上,指定其大小是不起任何作用的,因为C语言编译系统并不会检查形参数组大小,只是将实参数组的首元素的地址传给形参数组名。两者共同占用一存储单元。形参数组可以不指定大小,在定义数组时在数组名后面跟一个空的方括号(不指定大小)。
在学习了指针后,将float array[ ]转换为float*array(指针变量),两者等价。
多维数组名作函数参数
在被调用函数中对形参数组定义时可以指定每一维的大小,也可以省略第一维的大小说明。但不能把第2维以及其他高维的大小说明省略。
局部变量和全局变量
主要是变量的作用域问题
局部变量
在函数内部定义的变量为局部变量,只在本函数范围内有效。
不同函数中可以使用同名的变量,它们代表不同的对象,互不干扰。
形式参数也属于局部变量。
全局变量
在函数之外定义的变量为“外部变量”,即全局变量。它的作用范围是从定义位置到本源文件结束。设置全局变量作用虽然增加了函数间数据联系的通道,但通常建议不使用全局变量。原因:
(1)全局变量在程序的全部执行过程中都占用储存单元,不利于程序的快速运行。
(2)使函数的通用性降低,不利于函数的独立性,不是“模块化设计”的初衷。不利于函数展示的内聚性和对其他模块的耦合性。模块化的设计会使程序移植性变好,可读性增强。
(3)使用全局变量过多,会降低程序的清晰性。同时,在各个函数执行后可能改变外部变量的值,程序容易出错。
变量的存储方式和生存期
动态存储方式与静态存储方式
上面我们了解到变量可分为全局变量和局部变量。我们换另一个角度,即从变量值存在的时间(生存期)来观察。静态存储方式是指程序运行期间由系统分配固定的存储空间的方式。动态存储方式是在程序运行期间根据需要进行动态的分配存储空间的方式。
内存中供用户使用存储空间的情况。分为3部分:程序区,静态存储区,动态存储区。
数据分别放在静态存储区和动态存储区中。全局变量存储在静态存储区中,程序执行开始系统为其分配存储区,程序结束释放空间。
动态存储区存放:函数形式参数,函数定义中没有被static修饰的变量(即自动变量),函数调用时的现场保护和返回地址。函数执行开始系统为其分配存储区,函数结束释放空间。再用就新创。
在C语言中,每一个变量和函数都有两个属性:数据类型(整型,浮点型等)和数据的存储类别(在内存中的存储方式)。C的存储类别有4种:自动的(auto),静态的(static),寄存器的(register),外部的(extern)。
局部变量的存储类别
1.自动的(auto):在调用函数时,系统会给这一类变量分配空间,在函数调用结束后自动释放存储空间(放在动态存储区中)。关键词“auto”可以不写,隐含指定为自动存储类别。
2.静态存储类别(static):在函数调用后不消失并保留原值,即占用存储空间不释放。用“static”关键词声明。(在静态存储区中分配存储单元)
在定义局部变量时,没有赋初值,静态局部变量自动赋值为‘0’(对数值型变量)或‘\0’(字符型变量),自动局部变量是一个不确定的值。静态局部变量在函数调用后还存在,只能被本函数使用,不能被其他函数使用。用静态局部变量要多占用内存,而且降低了程序的可读性。非必要情况下,建议不使用。
3.寄存器变量(register):如果某些变量使用频繁,则存储花费时间,为了提高效率允许将局部变量放在CPU中的寄存器中,需要时直接从中取。编译系统会自动将其分类,无需人为指定。
全局变量的存储类别
1.在一个文件内扩展外部变量的作用域
如果需要使用作用域不到这里的变量时,要利用关键词“extern”将其作用域扩展到此处,为“外部变量声明”。建议:将外部变量的定义放在引用其的所有函数之前,可以避免再次加一个外部声明。
2.将外部变量的作用域扩展到其他文件
一个C程序可以由一个或多个源文件组成。在任一个文件中定义外部变量,而在另一个文件中用"extern"对“外部连接”作“外部变量声明”。同时依据全局变量的特性:使用时要注意全局变量值的改变。
那么多个“extrun”系统是怎么处理的?先在本文件上寻找,找不到,去外部文件中寻找,找不到,按出错处理。
3.将外部变量的作用域限制在本文件中
“static”声明,只能用于本文件的外部变量称为静态外部变量,以免被其他文件误用。
声明局部变量的存储类型和声明全局变量的存储类型的含义是不同的。对于局部变量,声明存储类型的作用是指定变量存储的区域(静态或动态)以及由此产生的生存期的问题,对于全局变量,都是在编译时分配内存的。都存放在静态存储区中,作用是变量作用域的扩展问题。
变量的声明和定义
函数由两个部分组成:声明部分和执行部分。声明部分的作用是对有关的标识符(如变量、函数、结构体、共用体等)的属性进行声明。
对于变量:声明:(1)需要建立存储空间,为定义性声明,简称声明。(2)不需要建立存储空间,为引用性声明。一般,把需要建立存储空间的声明称定义,把不需要建立存储空间的声明声明称为声明。(这里是狭义的,即非定义性声明)
外部变量的声明,作用:声明该变量是一个已在其他地方已定义的外部变量,仅仅为了扩展该变量的作用范围而作的“声明”。
内部变量和外部变量
依据:是否能被其他源文件调用
内部函数
一个函数只能被本文件中其他函数所调用,形式为:static 类型名 函数名(形参表);静态函数。
外部函数
加上关键词“exturn”的函数为“外部函数”,可供其他文件调用。形式:exturn类型名 函数名(形参表)。C语言规定,在定义时省略exturn,则默认为外部函数。将函数作用域扩展到其他文件。
函数原型(函数声明)扩展函数作用域常见的例子为#include指令的应用。在#include指令所指定的“头文件”中包含调用库函数时所需的信息。
P215题目
1.写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果。两个整数由键盘输入。
int Gcd(int a, int b)
{
int i;
for (i = a; i >= 1; i--)
{
if ((a % i == 0) && (b % i == 0))
{
break;
}
}
return i;
}
int Lcm(int m, int n)
{
int result_Lcm = m* n / Gcd(m, n);
return result_Lcm;
}
int main()
{
printf("这是一个求两个数最大公约数和最小公倍数的函数\n");
int x, y;
printf("请输入第一个数:");
scanf_s("%d", &x);
printf("请输入第二个数:");
scanf_s("%d", &y);
printf("最大公约数为%d\n",Gcd(x, y));
printf("最小公倍数为%d", Lcm(x, y));
return 0;
}
2.求方程的根,用3个函数分别求当:大于0,等于0和小于0时输出的结果。从主函数中输入a,b,c的值。
#include<math.h>
float d, x1, x2, x, s;
int main()
{
void Delta_2(float d, float b, float a);
void Delta_1(float a, float b, float d);
void Delta_0();
float a, b, c;
printf("请分别输入ax^2+bx+c=0的系数a、b、c:");
scanf_s("%f %f %f", &a,&b,&c);
d = b *b- 4*a*c;
if (d > 0)
{
Delta_2( d, b, a);
}
else if (d ==0)
{
Delta_1(a, b, d);
}
else if (d < 0)
{
Delta_0();
}
return 0;
}
void Delta_2(float d,float b,float a) //delta>0
{
s = sqrt(d);
x1 = (-b + s) / (2*a);
x2 = (-b - s) / (2*a);
printf("x1=%f,x2=%f", x1, x2);
}
void Delta_1(float a,float b,float d) //delta=0
{
float x;
x = (-b) / 2 * a;
printf("x=%f", x);
}
void Delta_0() //delta<0
{
printf("该函数无实数解");
}
3.写一个判素数的函数,在主函数输入一个整数,输出是否为素数的信息。
int main()
{
void judge_prime(int x);
int m;
printf("请输入:");
scanf("%d", &m);
judge_prime(m);
return 0;
}
void judge_prime(int x)
{
int count=0;
for (int i = 1; i <= x; i++)
{
if (x % i ==0)
{
count++;
}
}
if (count == 2) //1和本身
{
printf("是素数");
}
else if(count > 2)
{
printf("不是素数");
}
}
4.写一个函数,使给定的一个的二维整型数组转置,即行列互换。
int main()
{
void Trans_t(int arr1[][3]);
int arr1[3][3] = { 1,2,3,4,5,6,7,8,9 };
printf("原先为:\n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d ", arr1[i][j]);
}
printf("\n");
}
Trans_t(arr1);
printf("转置后为:\n");
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d ", arr1[i][j]);
}
printf("\n");
}
return 0;
}
void Trans_t(int arr[][3])
{
int i, j, t;
for (i = 0; i < 3; i++)
{
for (j = i+1; j < 3; j++)
{
t = arr[i][j];
arr[i][j] = arr[j][i];
arr[j][i] = t;
}
}
}
结果为:
5.写一个函数,使输入的一个字符串按反序存放,在主函数中输入输出字符串。
#include <stdlib.h>
#include <string.h>
void reverse(char str[]){
int len = strlen(str);
char temp;
for(int i = 0, j = len - 1; i <= j; i++, j--){
temp = str[i];
str[i] = str[j];
str[j] = temp;
}
}
int main(){
char str[80];
printf("Enter string: ");
gets(str);
reverse(str);
printf("New string: %s\n", str);
system("pause");
return 0;
}
6.写一个函数,将两个字符串连接。
int hehe(char str1[120], char str2[120])
{
int i = 0, j = 0;
printf("请输入第一个字符串:");
scanf("%s", str1);
printf("\n请输入第二个字符串:");
scanf("%s", str2);
while (str1[i] != '\0')
{
i++;
}
while (str2[j] != '\0')
{
str1[i] = str2[j];
i++;
j++;
}
str1[i] = '\0';
printf("\n两个字符串连接后:%s \n", str1);
return 0;
}
int main()
{
char str1[120], str2[120];//char数组大小最大为120
hehe(str1, str2);
return 0;
}
7.写一个函数,将一个字符串中的元音字母复制到另一字符串,然后输出。
void screen_vowel(char arr[],char arr2[])
{
int i=0, j=0;
while(arr[i]!='\0')
{
if (arr[i] == 'a' || arr[i] == 'e' || arr[i] == 'i' || arr[i] == 'o' || arr[i] == 'u')
{
arr2[j] = arr[i];
j++;
}
else
{
arr2[j] = '\0';
}
i++;
}
}
int main()
{
char a[100];
char b[100];
gets_s(a);
screen_vowel(a, b);
puts(b);
return 0;
}
8.写一个函数,输入一个4位数字,要求输出这4个数字字符,但每两个数字间空一个空格。如输入1990,应输出“1 9 9 0”。
#include<string.h>
int main()
{
void insert_space(char arr[]);
char arr[120];
printf("请输入:");
scanf("%s", arr);
insert_space(arr);
return 0;
}
void insert_space(char arr[])
{
for (int j = strlen(arr); j > 0; j--)
{
arr[2 * j] = arr[j];
arr[2 * j - 1] = ' ';
}
printf("表现为%s\n", arr);
}
9.编写一个函数,由实参传来一个字符串,统计此字符串中字母、数字、空格和其他字符的个数,在主函数中输入字符串以及输出上述的结果。
int letter, number, space, other;//全局变量
int main()
{
char arr[120];
printf("请输入:");
gets_s(arr);
void judge_string(char arr[]);
letter = 0, number = 0, space = 0, other = 0;
judge_string(arr);
printf("字符有%d个,数字有%d个,空格有%d个,其他字符有%d个",letter, number, space, other);
return 0;
}
void judge_string(char arr[])
{
for (int i = 0; arr[i]!='\0'; i++)
{
if (arr[i] >= 'A' && arr[i] <= 'Z' || arr[i] >= 'a' && arr[i] <= 'z')
letter++;
else if (arr[i] >= '0' && arr[i] <= '9')
number++;
else if (arr[i] == ' ')
space++;
else
other++;
}
}
10.写一个函数,输入一行字符,将此字符串中最长的单词输出。
#include<string.h>
#define N 30
int main()
{
void longest_word(char arr[]);
char arr[N];
gets_s(arr);
longest_word(arr);
return 0;
}
void longest_word(char arr[])
{
int a = 0, b;
int start = 0, end = 0;
int maxlen = 0;
unsigned long len = strlen(arr);//计算字符串长度,无\0
for (int i = 0; i < len + 1; i++) //+1,算上\0
{
if (arr[i] == ' ' || arr[i] == '\0') //以空格和\0作为隔断,拆分句子
{
b = i - 1;//单词的最后一个字符序号
if ((b - a + 1) > maxlen) //拆分并选出最长
{
maxlen = b - a + 1;
start = a;//新单词首部
end = b;//新单词尾部
}
a = i + 1;//跳过空格,开始新单词
}
}
for (int i = start; i <= end; i++)
{
printf("%c", arr[i]);
}
printf("\n");
}
11.写一个函数,用“起泡法”对输入得到10个字符按由小到大顺序排序。
#define N 10
void bubble_sort(char arr[])
{
for (int i = 1; i < N; i++)
{
for (int j =0;j< N - i; j++)
{
if (arr[j] > arr[j + 1])
{
char temp = arr[j + 1];
arr[j + 1] = arr[j];
arr[j ] = temp;
}
}
}
}
int main()
{
char arr[N];
printf("请输入:\n");
for (int i = 0; i < N; i++)
{
scanf("%c", &arr[i]);//直接输入一串字符,无需enter输入
}
bubble_sort(arr);
printf("排序为:\n");
for (int i = 0; i < N; i++)
{
printf("%c", arr[i]);
}
return 0;
}
结果为:
12.用牛顿迭代法求根。方程为,系数a,b,c,d的值依次为1,2,3,4由主函数输入。求x在1附近的一个实根。求出根后由主函数输出。
#include<stdio.h>
#include<math.h>
int main()
{
double Newton_method(int a, int b, int c, int d, double x1);
int a, b, c, d;
double x;
printf("请依次输入系数a,b,c,d的值:");
scanf_s("%d %d %d %d", &a, &b, &c, &d);
printf("请输入要在何处求值:");
scanf_s("%f", &x);
double x1 = Newton_method(a, b, c, d, x);
printf("其附近的根为%5.2f", x1);
return 0;
}
double Newton_method(int a,int b,int c,int d,double x1)
{
double x0, f, f1;
do
{
x0 = x1;
f = ((a * x0 - b) * x0 + c) * x0 - d;//原函数
f1 = ((a*3) * x0 - (b*2)) * x0 + c;//一阶导
x1 = x0 - f / f1;
} while (fabs(x1 - x0) >= 1e-5);//判断
return x1;
}
13.用递归方法求n阶勒让德多项式的值,递归公式为:
#include<stdio.h>
int main()
{
double my_legendre(int n, int x);
int x, n;
printf("请输入n和x的值:");
scanf_s("%d %d", &n, &x);
printf("n=%d,x=%d\n", n, x);
printf("P%d(%d)=%6.2f",n,x, my_legendre(n, x));
return 0;
}
double my_legendre(int n, int x)
{
if (n == 0)
return 1;
else if (n == 1)
return x;
else
return ((2 * n - 1) * x - my_legendre(n - 1, x) - (n - 1) * my_legendre(n - 2, x)) / n;
}
14.输入10个学生5门课的成绩,分别用函数实现下列功能:
(1)计算每个学生的平均成绩;(2)计算每门课的平均分;(3)找出所有50个分数中最高的分数所对应的学生和课程;(4)计算平均分方差:,其中,为某一学生的平均分。
#define P 10 //person的首字母
#define S 5 //subject的首字母
int main()
{
//声明
int option(void);
void select(int s);
void every_person_score(float arr[][S]);
void every_subject_score(float arr[][S]);
void people_max(float arr[][S]);
void variance(float arr[][S]);
float stu[P][S];
printf("请输入成绩:\n");
for (int i = 0; i < P; i++)
{
for (int j = 0; j < S; j++)
{
if (j == 0)
{
printf("第%d个学生的成绩:", i + 1);
}
scanf("%f", &stu[i][j]);
}
}
printf("\n");
int s = option();
select(s);
//选择功能
switch (s)
{
case 1:every_person_score(stu);
break;
case 2:every_subject_score(stu);
break;
case 3:people_max(stu);
break;
case 4:variance(stu); break;
}
return 0;
}
//菜单函数
int option(void)
{
int s;
printf("请选择功能:\n");
printf("1.计算每个学生的平均成绩\n");
printf("2.计算每门课的平均分\n");
printf("3.找出所有50个分数中最高的分数所对应的学生和课程\n");
printf("4.计算平均分方差\n");
printf("请输入:");
scanf("%d", &s);
return s;
}
void select(int s)
{
switch (s)
{
case 1:printf("计算每个学生的平均成绩\n"); break;
case 2:printf("计算每门课的平均分\n"); break;
case 3:printf("找出所有50个分数中最高的分数所对应的学生和课程\n"); break;
case 4:printf("计算平均分方差\n"); break;
}
}
//功能函数
void every_person_score(float arr[][S])
{
float aver[P];
for (int i = 0; i < P; i++)
{
float sum = 0;
for (int j = 0; j < S; j++)
{
sum+= arr[i][j];
}
aver[i] = sum/P;
printf("第%d个学生的平均成绩:%5.2f\n", i+1,aver[i]);
}
}
void every_subject_score(float arr[][S])
{
float aver[P];
for (int j = 0; j < S; j++)
{
float sum = 0;
for (int i = 0; i < P; i++)
{
sum += arr[i][j];
}
aver[j] = sum/S;
printf("第%d门课的平均成绩:%5.2f\n", j + 1, aver[j]);
}
}
void people_max(float arr[][S])
{
float Max;
int row = 0, colum = 0, i, j;
Max = arr[0][0];
for (i = 0; i < P; i++)
{
for (j = 0; j < S-1; j++)
{
if (arr[i][j] > Max)
{
Max = arr[i][j];
row = i;
colum = j;
}
}
}
printf("第%d位学生的第%d门成绩为最高:%f", row + 1, colum + 1, Max);
}
void variance(float arr[][S])
{
float aver[P];
double squ = 0, var_1 = 0, var_2 = 0, var;
for (int i = 0; i < P; i++)
{
float sum = 0;
for (int j = 0; j < S; j++)
{
sum += arr[i][j];
}
aver[i] = sum / P;
var_1 = aver[i] * aver[i];
squ += var_1;
var_2 += aver[i];
}
var = squ /P -(var_2/P) * (var_2/P);
printf("%6.3f\n", var);
}
15.写几个函数:(1)输入10个职工的姓名和职工号;(2)按职工号由小到大顺序。姓名顺序也随之调整;(3)要求输入一个职工号,用拆半查找法找出该职工的姓名,从主函数输入要查找的职工号,输入该职工姓名。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 10
void inputEmployee(char employeeName[][20], int employeeNo[], int n)
{
for (int i = 0; i < n; i++)
{
printf("Enter No.%d employee name: ", i + 1);
gets_s(employeeName[i]);
printf("Enter No.%d employee number: ", i + 1);
scanf("%d", &employeeNo[i]);
while (employeeNo[i] <= 0)
{
printf("Number Error! Retry!\nEnter No.%d employee number: ", i++);
scanf("%d", &employeeNo[i]);
}
getchar();
}
}
void ascendingSort(char employeeName[][20], int employeeNo[], int n)
{
char tempName[20];
int tempNo;
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
if (employeeNo[i] > employeeNo[j])
{
tempNo = employeeNo[i];
employeeNo[i] = employeeNo[j];
employeeNo[j] = tempNo;
strcpy(tempName, employeeName[i]);
strcpy(employeeName[i], employeeName[j]);
strcpy(employeeName[j], tempName);
}
}
}
}
int search(char employeeName[][20], int employeeNo[], int n, int searchNo, char searchName[])
{
int low = 0;
int high = n - 1;
int mid;
int pos = -1;
while (low <= high)
{
mid = (low + high) / 2;
if (searchNo < employeeNo[mid])
{
high = mid - 1;
}
else if (searchNo > employeeNo[mid])
{
low = mid + 1;
}
else
{
pos = 1;
strcpy(searchName, employeeName[mid]);
break;
}
}
return pos == -1 ? 0 : 1;
}
int main() {
char employeeName[N][20];
int employeeNo[N];
int searchNo;
char searchName[20];
int sign;
inputEmployee(employeeName, employeeNo, N);
ascendingSort(employeeName, employeeNo, N);
printf("\nEnter search number: ");
scanf("%d", &searchNo);
sign = search(employeeName, employeeNo, N, searchNo, searchName);
if (sign == 1)
{
printf("Name: %s\n", searchName);
}
else {
printf("No Record!\n");
}
return 0;
}
16.写一个函数,输入一个十六进制数,输出相应的十进制数。
#include <stdio.h>
#include <math.h>
#include <string.h>
int main()
{
char a[10];
void convert(char a[]);
printf("请输入十六进制数:");
gets_s(a); //输入十六进制数
convert(a);
return 0;
}
void convert(char a[])
{
int n, i, num = 0;
n = strlen(a);
for (i = n - 1; i >= 0; i--)
{
if (a[i] >= '0' && a[i] <= '9')
num += (a[i] - '0') * pow(16, n - 1 - i);
else if (a[i] >= 'A' && a[i] <= 'F')
num += (10 + (a[i] - 'A')) * pow(16, n - 1 - i);
else if (a[i] >= 'a' && a[i] <= 'f')
num += (10 + (a[i] - 'a')) * pow(16, n - 1 - i);
}
printf("转换十进制为:");
printf("%d", num);
}
17.用递归法将一个整数n转换成字符串。例如,输入483,应输出字符串“483”。n的位数不确定,可以是任意位数的整数。
#include<stdio.h>
void convert(int n) {
int i;
if ((i = n / 10) != 0)
convert(i);
putchar(n % 10 + '0');
}
int main() {
int num;
scanf("%d", &num);
if (num < 0) {
printf("-");
num = -num;
}
convert(num);
printf("\n");
return 0;
}
18.给出年、月、日,计算该日是该年的第几天。
#include<stdio.h>
int flag(int year)//判断是否是闰年
{
int s = 0;
if (year % 4 == 0 && year % 400 != 0 || year % 100 == 0 && year % 400 == 0)
s = 1;
return s;
}
int date(int mon, int day)//计算时间天数
{
int s = 0;
int a[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
for (int i = 0; i < mon - 1; i++)
s = s + a[i];
s = s + day;
return s;
}
int main()
{
int year, mon, day, sum, p;
printf("输入日期:");//键盘输入日期
scanf("%d%d%d", &year, &mon, &day);
sum = date(mon, day);//计算天数
p = flag(year);
if (mon >= 3 && p == 1)//闰年要多一天
sum++;
printf("%d年%d月%d日是这一年的第%d天\n", year, mon, day, sum);
}