任务1素数判
写一个判断素数的函数,在主函数输入一个整数,输出是否为素数的信息。
本关知识
定义函数的方法
C
语言中的函数定义的一般形式如下:
类型名 函数名(形式参数表列 )
{
函数体
}
在C
语言中,函数由一个函数头和一个函数主体组成。下面列出一个函数的所有组成部分: 返回类型:一个函数可以返回一个值。类型名是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,类型名是关键字void
。 函数名称:这是函数的实际名称。函数名和参数列表一起构成了函数签名。 形式参数:函数名后括号中的参数是形式参数,在调用次函数时,主调函数把实际参数的值传递给被调用函数中的形式参数。形式参数是可选的,也就是说,函数可能不包含参数。 函数主体:花括号内的部分称为函数体,它可以包括声明部分和语句部分。声明部分包括对函数中用到的变量进行定义以及对要调用的函数进行声明等内容。
例如,下面的max()
函数是求两个数中较大的那个数:
/* 函数返回两个数中较大的那个数 */
int max(int num1,int num2)
{
/* 局部变量声明 */
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
函数声明
函数声明会告诉编译器函数名称及如何调用函数。函数的实际主体可以单独定义。 函数声明包括以下几个部分: 函数类型 函数名( 参数表列 ); 针对上面定义的函数 max()
,以下是函数声明: int max(int num1, int num2);
在函数声明中,参数的名称并不重要,只有参数的类型是必需的,因此下面也是有效的声明: int max(int, int);
当在一个源文件中定义函数且在另一个文件中调用函数时,函数声明是必需的。在这种情况下,您应该在调用函数的文件顶部声明函数。
调用函数
创建C
函数时,会定义函数做什么,然后通过调用函数来完成已定义的任务。 当程序调用函数时,程序控制权会转移给被调用的函数。被调用的函数执行已定义的任务,当函数的返回语句被执行时,或到达函数的结束括号时,会把程序控制权交还给主程序。 调用函数时,传递所需参数,如果函数返回一个值,则可以存储返回值。
例如:
#include <stdio.h>
/* 函数声明 */
int max(int num1, int num2);
int main ()
{
/* 局部变量定义 */
int a = 100;
int b = 200;
int ret;
/* 调用函数来获取最大值 */
ret = max(a, b);
printf( "Max value is : %d\n", ret );
return 0;
}
/* 函数返回两个数中较大的那个数 */
int max(int num1, int num2)
{
/* 局部变量声明 */
int result;
if (num1 > num2)
result = num1;
else
result = num2;
return result;
}
补充说明: 形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁。 当调用函数时,有两种向函数传递参数的方式: 传值调用:该方法把参数的实际值复制给函数的形式参数。在这种情况下,修改函数内的形式参数不会影响实际参数。 引用调用:通过指针传递方式,形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作。 默认情况下,C
使用传值调用来传递参数。一般来说,这意味着函数内的代码不能改变用于调用函数的实际参数。
函数的返回值
函数的返回值是通过函数中的return
语句获得的。return
语句将被调用函数中的一个确定值带回到主调函数中去。 一个函数中可以有一个以上的return
语句,执行到哪一个return
语句,哪一个return
语句就起作用。return
语句后的括号可以不要,如“return z;”
与“return (z);”
等价。 需要注意的是,在定义函数时指定的函数类型一般应与return
语句中的表达式类型一致。
编程要求
本关的编程任务是补全IsPrime.c
文件中main函数,以实现素数判断的功能。 实际的测试样例参见下文。 本关涉及的代码文件IsPrime.c
的代码框架如下:
//包含标准输入输出函数
#include<stdio.h>
//基本框架如下,请在此添加‘素数判断’的代码
/********** 修改以下代码 **********/
...
int main(){
scanf(...);
isPrime(...);
...
return 0;
}
//函数主体
void isPrime(...){
...
}
/* or
int isPrime(...){
...
}
or else
...
*/
/********** 修改代码区间 **********/
其中: #include <stdio.h>
的意思是包含stdio
函数库,使得当前程序可以调用标准输入输出函数库中的函数。
测试说明
本关的测试过程如下:
- 平台编译
IsPrime.c
,然后链接相关程序库并生成IsPrime.exe
; - 平台运行
IsPrime.exe
,并以标准方式提供测试输入; - 平台获取
IsPrime.exe
的输出,然后将其与预测输出对比,如果一致则测试通过;否则测试失败。 以下是平台对IsPrime.c
的测试样例:
测试输入: 5
预期输出: 5是一个素数
测试输入: -10
预期输出: -10不是一个素数
测试输入: 18
预期输出: 18不是一个素数
测试输入: 1
预期输出: 1不是一个素数
//包含标准输入输出函数
#include<stdio.h>
//基本框架如下,请在此添加‘素数判断’的代码
/********** 修改以下代码 **********/
int main(){
void isPrime(int n);
int a;
scanf("%d",&a);
isPrime(a);
return 0;
}
//函数主体
void isPrime(int n){
int i;
for(i=2;i<=n-1;i++)
if(n%i==0)
break;
if(i==n)
printf("%d是一个素数",n);
else
printf("%d不是一个素数",n);
}
/* or
int isPrime(...){
...
}
or else
...
*/
/********** 修改代码区间 **********/
任务2递归法将一个整数n转换成字符串
用递归法将一个整数n转换成字符串,然后输出,输出时要求各个字符之间用空格隔开。例如,输入483
,应输出字符串“4 8 3”
。n
的位数不确定,可以是任意位数的整数。
解题提示
1)如果是负数,要把它转换为正数,同时人为地输出一个“-
”号。 2)可以用putchar(n%10+'0')
或putchar(n%10+48)
来输出一个字符。 3)可以用putchar(32)
来输出一个空格。
本关知识
函数的递归调用
在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的递归调用。 例如:
int fun(int x){
int y,z;
z = f(y); //在执行f函数的过程中又要调用f函数
return (2*z);
}
在调用f函数的过程中,又要调用f函数,这就是直接调用。 如果在调用f1
函数的过程中又要调用f2
函数,而在调用f2
函数过程中又要调用f1
函数,这就是间接调用本函数。 上面的例子中,递归调用是无终止的自身调用。显然,程序中不应出现这种无终止的递归调用,而只应出现有限次数的、有终止的递归调用,这可以用if
语句来控制,只有在某一条件成立时才继续执行递归调用,否则就不再继续。
编程要求
本关的编程任务是补全FigureTrasform.h
文件中figureTrasform
的函数,以实现用递归法将一个整数n
转换成字符串的功能。 实际的测试样例参见下文。 本关涉及的代码文件FigureTrasform.h
的代码框架如下:
#include<stdio.h>
void figureTrasform(int n){
//在此写入函数体
//在函数体内实现输出
//注意主函数,非常重要
/*****************Begin******************/
/***************** End ******************/
}
主函数如下: #include<stdio.h> #include<string.h>
//此处已导入 FigureTransform.h头文件
//所以下面的函数调用不需要再进行声明
#include"FigureTransform.h"
//主函数
#include<stdio.h>
#include<string.h>
//此处已导入 FigureTransform.h头文件
//所以下面的函数调用不需要再进行声明
#include"FigureTransform.h"
//主函数
int main(){
long n;
scanf("%d",&n);
if(n==0){ //如果输入的n是0,则输出‘0’,结束。
putchar('0');
return 0;
}
figureTrasform(n); //调用数字转换函数
return 0;
}
测试说明
本关的测试过程如下:
- 平台编译
FigureTrasformMain.c
以及头文件FigureTransform.h
,然后链接相关程序库并生成FigureTrasformMain.exe
以及FigureTransform.h.gch
; - 平台运行
FigureTrasformMain.exe
,并以标准方式提供测试输入; - 平台获取
FigureTrasformMain.exe
的输出,然后将其与预测输出对比,如果一致则测试通过;否则测试失败。 以下是平台对FigureTrasformMain.c
的测试样例:
测试输入: 123456789
预期输出: 1 2 3 4 5 6 7 8 9
测试输入: -1314520
预期输出: ``-1 3 1 4 5 2 0
测试输入: 30569870
预期输出: 3 0 5 6 9 8 7 0
#include<stdio.h>
void figureTrasform(int n){
//在此写入函数体
//在函数体内实现输出
//注意主函数,非常重要
/*****************Begin******************/
if(n < 0){
n = -n;
putchar('-');
putchar(32);
}
if(n / 10) figureTrasform(n / 10);
putchar(n % 10 + 48);
putchar(32);
/***************** End ******************/
}
任务3字符串反序输出
写一个函数,使输入的一个字符串按反序存放,在主函数中输入和输出字符串。
本关知识
数组作为函数参数
数组可以作为函数的参数使用,进行数据传送。
数组用作函数参数有两种形式,一种是把数组元素(下标变量)作为实参使用;另一种是把数组名作为函数的形参和实参使用。
数组元素作函数实参
数组元素就是下标变量,它与普通变量并无区别。 因此它作为函数实参使用与普通变量是完全相同的,在发生函数调用时,把作为实参的数组元素的值传送给形参,实现单向的值传送。
数组名作为函数参数
用数组名作函数参数与用数组元素作实参有几点不同。
-
用数组元素作实参时,只要数组类型和函数的形参变量的类型一致,那么作为下标变量的数组元素的类型也和函数形参变量的类型是一致的。因此,并不要求函数的形参也是下标变量。换句话说,对数组元素的处理是按普通变量对待的。用数组名作函数参数时,则要求形参和相对应的实参都必须是类型相同的数组,都必须有明确的数组说明。当形参和实参二者不一致时,即会发生错误。
-
在普通变量或下标变量作函数参数时,形参变量和实参变量是由编译系统分配的两个不同的内存单元。在函数调用时发生的值传送是把实参变量的值赋予形参变量。 在用数组名作函数参数时,不是进行值的传送,即不是把实参数组的每一个元素的值都赋予形参数组的各个元素。因为实际上形参数组并不存在,编译系统不为形参数组分配内存。那么,数据的传送是如何实现的呢?我们曾介绍过,数组名就是数组的首地址。因此在数组名作函数参数时所进行的传送只是地址的传送,也就是说把实参数组的首地址赋予形参数组名。形参数组名取得该首地址之后,也就等于有了实在的数组。实际上是形参数组和实参数组为同一数组,共同拥有一段内存空间。
字符串函数的使用
在使用字符串函数前应使用以下命令包含头文件 #include <string.h>
用求字符串长度的函数strlen求字符串的长度,如 int j = strlen(str); //str是一个字符数组
编程要求
本关的编程任务是补全ReverseOutput.c
文件中main函数,以实现字符串反序输出的功能。 实际的测试样例参见下文。 本关涉及的代码文件ReverseOutput.c
的代码框架如下:
//包含标准输入输出函数
#include<stdio.h>
//字符串处理函数
#include<string.h>
//基本框架如下,请在此添加‘反序输出’的代码
/********** 修改以下代码 **********/
...
int main(){
scanf(...);
reverseOutput(...);
...
return 0;
}
//函数主体
char reverseOutput(...){
...
}
/* or
int reverseOutput(...){
...
}
or else
...
*/
/********** 修改代码区间 **********/
其中: #include <stdio.h>
的意思是包含stdio
函数库,使得当前程序可以调用标准输入输出函数库中的函数。
测试说明
本关的测试过程如下:
- 平台编译
ReverseOutput.c
,然后链接相关程序库并生成ReverseOutput.exe
; - 平台运行
ReverseOutput.exe
,并以标准方式提供测试输入; - 平台获取
ReverseOutput.exe
的输出,然后将其与预测输出对比,如果一致则测试通过;否则测试失败。 以下是平台对ReverseOutput.c
的测试样例:
测试输入: 123456789
预期输出: 987654321
测试输入: zhousiheng
预期输出: gnehisuohz
#include <stdio.h>
#include <string.h>
int main(){
void rev(char a[]);
//输入字符串
char str1[80];
scanf("%s",str1);
rev(str1);
//输出字符串
printf("%s\n",str1);
return 0;
}
void rev(char a[])
{
int i, j, k;
char t;
k=strlen(a);
for (i=0, j=k-1; i<k/2; i++, j--){
t=a[i];
a[i]=a[j];
a[j]=t;
}
}