阶乘if函数多个条件怎么用求值,如下if语句中else部分,如何实现阶乘的过程?看不懂else语句部分

在我们面试时通常会遇到阶乘的问题,当然最简单的就是运用递归,循环所求的阶乘数:
不多数,直接上代码:
* 实现10的阶乘
* @author fx * */
public class JieCheng {
public static void main(String[] args) {
System.out.println(getFactorialSum(10)+"");//通过循环实现阶乘
int sum=1,n=10;
for(int i=1;i&=n;i++){
sum=sum*i;
System.out.println(sum);
//通过递归实现阶乘
private static int getFactorialSum(int n){
if(n==1||n==0){
return getFactorialSum(n-1)*n;
当我们到13的阶乘时,则会计算不出,这时我们可以把int类型转换成long类型,但是,当计算到很大的数字时,也会运行异常。
这时,我们需要转换一下思维。这里运用采用 “数组进位” 算法。在超越计算机变量取值范围的情况下,将多位数相乘转化为一位数相乘。如11!=,若需求12的阶乘,则需要将相乘,可利用乘法分配率。乘法竖式如下图所示:
理论上讲,只要计算机内存空间允许就可以保存任意多位的阶乘结果,不再受变量的取值范围的限制,只受到操作系统的寻址能力和计算机内存的限制。如果要求的阶乘数字很大则可以将数组定义为 long 类型,以避免在计算单位数的乘积时出现溢出的情况。不多说了,上代码:
* Created by fx.
public class BigInteger
* 计算进位
* @param bit
* @param pos 用于判断是否是数组的最高位
private void carry(int[] bit, int pos)
int i ,carray = 0;
for(i = 0 ; i&=i++)//从0到pos逐位检查是否需要进位
bit[i] +=//累加进位
if(bit[i] &= 9)
//小于9不进位
carray = 0;
else if(bit[i] &9 && i 9 && i &= pos)//大于9,且是最高位
while(bit[i] & 9)//循环向前进位
carray = bit[i]/10;//计算进位值
bit[i] = bit[i] % 10;//当前的第一位数
bit[i] =//在下一位保存进位值
* 大整数阶乘
* @param bigInteger 所计算的大整数
void bigFactorial(int bigInteger)
int pos =0;//
//数据长度
int m = 0 ;//统计输出位数
= 0 ;//统计输出行数
double sum = 0;//阶乘位数
for(a = 1 ; a &= bigI a ++)//计算阶乘位数
sum += Math.log10(a);
digit = (int)sum + 1;//数据长度
int[] fact = new int[digit];//初始化一个数组
= 1;//设个位为 1
for(a = 2 ; a &= bigI a++ )//将2^bigInteger逐个与原来的积相乘
for(b = digit-1 ; b &= 0 ; b--)//查找最高位{}
if( fact[b]
pos =//记录最高位
for(b = 0; b &= b++)
fact[b] *=//每一位与i乘
carry(fact,pos);
for(b = digit-1 ; b &= 0 ; b --)
if(fact[b] != 0)
pos =//记录最高位
System.out.println(bigInteger +"阶乘结果为:");
for(a = a &= 0 ; a --)//输出计算结果
System.out.print(fact[a]);
if(m % 5 == 0)
System.out.print(" ");
if(40 == m )
System.out.println("");
if(10 == n )
System.out.print("\n");
System.out.println("\n"+"阶乘共有: "+(pos+1)+" 位");
public void doBigFactorial(int bigInteger)
int timeBegin=(int) System.currentTimeMillis();
this.bigFactorial(bigInteger);
int timeFinishi=(int) System.currentTimeMillis();
int time = timeFinishi-timeB
System.out.println("计算耗时: " + time +"毫秒" );
public static void main(String[] args)
BigInteger bi = new BigInteger();
bi.doBigFactorial(100000);
此处计算的100000的阶乘(当然可以修改成其他数字)。
结果如下:
小算法,关于阶乘数字过大溢出的解决办法
思路:假设372为一个大数字,18为一个普通int型数字
代码如下:
public class Demo01 {
//求一个数的阶乘,当求一个很大的数的阶乘,会造成数据溢出
//解决办...
算法实现求n的阶乘(防止溢出)
求大整数n阶乘,在找工作笔试和面试的过程中,不止一次遇到这个问题,用一个for循环迭代出的结果肯定是不行的,即直接用int,默认是32位,它能表示的最大值为2,147,483,647,但是12的阶乘为...
阶乘最大值
int n,只能算到12!
long long int,只能算到20!
我的代码:
int main()
long lon...
java中超出long范围的数的大数阶乘解法并求尾零,运用BigDecimal类
package day1;import java.math.BigD/** *
* @author zjs * */public class Solution {
public ...
蓝桥杯 阶乘 解决溢出问题
这道题可能很多一看就知道要解决溢出问题,然后就使用long long,但其实使用long long在算100的阶乘就已经严重溢出了,所以更合理的办法是像题目中提示的一样,使用一个数组,代码如下:#in...
int main()
long long a[15];
for (i = 3;i & 1...
求一个较大数的&em&阶乘&/em&!例如100!将&em&超过long&/em&的表示&em&范围&/em&,本程序将告诉你一种简单而有效的方法。-本人在Visual Studio2008下编译通过,希望大家喜欢。
题目描述计算a + b。a和b是整数。(0 ≤ A,B ≤10 30)。输入输入可能包含几个测试用例。在每个测试用例中,有两个整数a和b,用空格分隔。输入由EOF终止。输出对于每个测试用例,打印出a和...
每一个case都WA过不计其数
题目链接:点击打开链接
注:详解大数阶乘,希望对有需要的人有帮助。
时间限制:3000 ms
内存限制:65535 KB
描述我们都知道如何计算一个数的阶乘...
没有更多推荐了,#include&stdio.h&
int fun(int n)
if(n==0||n==1)
n=n*fun(n-1);
int main()
printf("请输入一个数字:\n");
scanf("%d",&i);
printf("它的阶乘为: %d",j);
测试结果:
相比于传统的利用循环计算阶乘:
#include&stdio.h&
int main()
int i=1,n;
int sum=1;
printf("输入一个正的数字:\n");
scanf("%d",&n);
for(i=1;i&=n;i++)
sum=sum*i;
printf("它的阶乘为:%d",sum);
我们发现调用函数递归计算的运算时间要比循环计算阶乘的时间长。
用C++调用递归函数计算阶乘
作者:小岛的水
//调用递归函数计算阶乘
int main()
int fac...
递归计算N阶乘
递归计算N阶乘// 递归计算N阶乘.cpp : 定义控制台应用程序的入口点。
//#include &stdafx.h&
#includelong Factoria...
C语言通过递归调用函数解决求阶乘和ACKERMAN函数问题
输入整型n(n&=0),输出n!
int fac(int n)
if(n==1||n==0) sum=1;
else sum=n*fac...
C语言使用递归法计算n的阶乘
C语言使用递归法计算n的阶乘#include
long Fact(int n);
int main(){
printf(&Input n:&...
//递归函数求一个数的阶乘
int factorial();int main()
printf(&-----输入一个阶乘-----\n&);
函数的递归调用标签(空格分隔): 双学位高级语言程序设计 C C函数在函数中直接或间接的调用自己,就称为递归调用
看下面这个求阶乘的例子
求n的阶乘,数学函数形式是这样的
文章出自个人博客https://knightyun.github.io//recursion-factorial,转载请申明
在编程中函数有一个神奇又难理解的功能...
利用递归函数求阶乘主要是设置递归函数的边界条件和递归公式,详细代码示例如下:
#include &iostream&
递归问题是一个说简单也简单,说难也有点难理解的问题.我想非常有必要对其做一个总结.
首先理解一下递归的定义,递归就是直接或间接的调用自身.而至于什么时候要用到递归,递归和非递归又有那些区别?又是一个...
没有更多推荐了,当前位置: >>
C语言二级上机考试填空100道(历年考题都是从中抽取的)完美打印版
} else (1)题目: 请补充 fun 函数, 函数的功能是求 10 的阶乘。 fun 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在 fun 函数的横线上填入所编写的若干表达式或 语句。 #include &stdio.h& long fun ( int { if (___1___) return (n*fun(___2___)); else if (___3___) return 1; } main() { int k = 10 ; printf(&%d!=%ld\n&, k, fun ( k )) ; } 分析: 整个程序是计算 10 的阶乘, 而 n 的阶乘是这样计 算的: n!=n*(n-1)*(n-2)*(n-3)*…*3*2*1 其中 n&0 并且 n 为自然数。 所以, 的阶乘就是计算 10*9*8*7*6*5*4*3*2*1 10 的结果, 换句话说就是计算 1 至 10 之间所有自然数 的乘积。从程序来看,fun 函数就是计算阶乘的函 数,但是在 fun 函数中又调用了自己,即第五行 &return (n*fun(___2___));&中 fun 函数又调用了 fun 函数,这种函数自己调用自身的现象在程序设计中 称为递归,使用递归这种程序设计方法对设计人员 的程序设计能力有较高的要求。 计算阶乘是递归程序设计的一个经典示例。计算 某个数的阶乘就是用那个数去乘包括 1 在内的所 有比它小的数。例如,fun(5)等价于 5*4*3*2*1,而 fun(3)等价于 3*2*1。 阶乘的一个有趣特性是,某个数的阶乘等于起始 数(starting number)乘以比它小一的数的阶乘。例 如,fun(5)与 5 * fun(4)相同。您很可能会像这样编 写阶乘函数 fun: int fun(int n) { return n * fun(n - 1); } 不过,这个函数的问题是,它会永远运行下去, 因为它没有终止的地方。函数会连续不断地调用 fun。当计算到零时,没有条件来停止它,所以它会 继续调用零和负数的阶乘。因此,我们的函数需要 一个条件,告诉它何时停止。 由于小于 1 的数的阶乘没有任何意义, 所以我们 在计算到数字 1 的时候停止, 并返回 1 的阶乘 (即 1) 。因此,真正的递归函数类似于: int fun(int n) { if(n == 1) { return 1; (3)题目: 请补充函数 fun(char *s),该函数的功能是把字 分析: 从题意可以得知本题计算的是斐波纳契数列,斐 波纳契数列的计算方法由题目得知该数列中每数等 于前面两数之和,如 0 1 1 2 3 5 8 13 ……,这样我 们可以列出以下计算斐波纳契数列的公式: fun(0)=0 fun(1)=1 fun(n)=fun(n-1)+fun(n-2) 当 n=0 当 n=1 当 n&1 } else return ___3___; else if(___2___) return 1; } int fun(int n) { if(___1___) return 0; n) } (2)题目: 请在函数 fun 的横线上填写若干表达式,使从键 盘上输入一个整数 n,输出斐波纳契数列。斐波纳 契数列是一种整数数列,其中每数等于前面两数之 和,如 0 1 1 2 3 5 8 13 …… 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在 fun 函数的横线上填入所编写的若干表达式或 语句。 #include &stdio.h& int fun(int n); main() { int i,n=0; scanf(&%d&,&n); for( i=0;i&n;i++) printf(&%d &, fun ( i )); } { return n * fun(n - 1);符串中的内容逆置。 例如:字符串中原有的字符串为 abcde,则调用 该函数后,串中的内容为 edcba。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在 fun 函数的横线上填入所编写的若干表达式或 语句。 #include &string.h& #include &conio.h& #include &stdio.h& #define N 81 void fun(char *s) { int i=0,t,n=strlen(s); for(;___1___;i++) { t=*(s+i); ___2___; ___3___; } } main() { char a[N]; clrscr(); printf(&Enter a string:&); gets(a); printf(&The original string is:&); puts(a); fun(a); printf(&\n&); printf(&The string after modified:&); puts(a); } 分析: 将字符串中的内容逆置主要思路分析如下: (1) 在字符串第一个字母位置和最后一个字母位 置各自设置一个指示器 A 和 B,它们分别指向第一 个字母和最后一个字母, 然后 A 位置的字母和 B 位 置的字母进行互换。 (2)互换结束之后指示器 A 移动到第二个字母, 而指示器 B 移动到倒数第二个字母, 即指示器 A 往 后移动一个字母位置,而指示器 B 往前移动一个字 母位置, 然后 A 位置的字母和 B 位置的字母进行互 换。 (3)互换结束之后指示器 A 往后再次移动一个 字母位置, 而指示器 B 再次往前移动一个字母位置, 然后 A 位置的字母和 B 位置的字母进行互换。 (4)以上过程反复进行,只有指示器 B 的位置 小于指示器 A 的位置, 即指示器 B 指向的位置在指 示器 A 指向的位置的左边的情况下才结束,所以以 上过程可以使用循环语句实现,循环终止条件可以 判断指示器 B 的位置是否小于指示器 A 的位置。 为了实现以上思路, 我们观察 fun 函数。fun 函数 的功能就是将传入的 s 参数作为字符串进行内容逆 置,它的逆置方法和我们分析的思路是一致的。它 使用了 for 循环语句进行循环,循环体中使用指针 s+i 作为指示器 A,而指示器 B 使用 s+n-1-i 表示。 其中 i 每次循环加一,而 n=strlen(s),为传入的字符当 n 等于 0 的时候,即计算斐波纳契数列的第一 个数字,根据题目知道该数列的第一个数字为 0。 当 n 等于 1 的时候,即计算斐波纳契数列的第二 个数字,根据题目知道该数列的第二个数字为 1。 当 n 等于 2 的时候,即计算斐波纳契数列的第三 个数字,由于该数列中每数等于前面两数之和,所 以 fun(2)=fun(1)+fun(0)。 当 n 等于 3 的时候,即计算斐波纳契数列的第四 个数字,由于该数列中每数等于前面两数之和,所 以 fun(3)=fun(2)+fun(1)。 …… 所以当 n 大于 1 的时候, fun(n)=fun(n-1)+fun(n-2)。 这里存在函数调用本身的现象,这种现象在程序 设计中称为递归。 串的长度。 strlen 函数可以得到 s 参数的字符串中包 含的字母个数。 为什么指针 s+i 可以作为指示器 A 呢?由于指针 s 对应 main 函数传入的 a 数组, C 语言中数组名 而 称就是一个指向数组第一个元素的指针,所以数组 a 的名称 a 就是一个 char 类型的指针, 即为 char *。 所以指针 s 指向传入的字符串的第一个字母,所以 可以使用 s 作为指示器 A 的初始值。而每次循环 i 都加一,在 C 语言语法中,一个指针加上一个整数 表示一个新指针,该指针指向原指针向后移动所加 上整数个数的位置,所以 s+1 指向字母&b&,s+2 指 向字母&c&,依次类推。 那为什么 s+n-1-i 可以作为指示器 B 呢?如果传 入的字符串为&abcde&,s 指针指向字母&a&,n 为字 符串为&abcde&的长度,即字符串&abcde&的字母个 数,即为 5。一个指针加上一个整数表示一个新指 针,该指针指向原指针向后移动所加上整数个数的 位置,所以 s+5 表示指向从字母&a&向后移动 5 个位 置的新指针,即字母&e&后面一个位置,而我们希望 指示器 B 指向字母&e&, 所以 s+n-1 才是指示器 B 的 初始值。每次循环 i 都加一,在 C 语言语法中,一 个指针减去一个整数表示一个新指针,该指针指向 原指针向前移动所减去整数个数的位置。 例如 s+n-1 指向字母&e&,s+n-1-1 指向字母&d&,s+n-1-2 指向字 母&c&,依次类推。 进行逆置的 for 循环终止条件是判断指示器 A 的 位置是否在指示器 B 的位置的右边,那么循环继续 的条件就是指示器 A 的位置应该在指示器 B 的位置 的左边。根据 C 语言的语法,指针 P1 在指针 P2 的 左边可以使用 P1&P2 表示。所以 fun 函数第一个填 空处应该填写指示器 A&指示器 B,即 s+i&s+n-1-i。 分析到这里,fun 函数剩下的两个填空应该填写 什么呢?for 循环体中应该进行指示器 A 和指示器 B 两个位置的字母互换。 t=*(s+i);语句先把指示器 A 位置的字母保存在 t 变量中,然后将指示器 B 位置 的字母覆盖指示器 A 位置的字母,然后将预先保留 在 t 变量中的指示器 A 位置的字母覆盖指示器 B 位 置的字母,这样即完成两个位置的字母互换。 根据 C 语言的语法,取得指针指向位置的值应该 使用*运算符。所以指示器 A 位置的字母使用*(s+i) 表示,而指示器 B 位置的字母使用*(s+n-1-i)表示, 所以第二处填空处应该填写*(s+i)=*(s+n-1-i),而第 三处填空处应该填写*(s+n-1-i)=t。 程序注解如下: #include &string.h& #include &conio.h& #include &stdio.h& #define N 81 /* fun 函数的功能是把字符串中的内容逆置 */ void fun(char *s) { /* 定义存放要逆置的字符串的字符数组 */ int i=0,t,n=strlen(s); for(;s+i&s+n-1-i;i++) { t=*(s+i); *(s+i)=*(s+n-1-i); *(s+n-1-i)=t; } }main() { /* 定义存放要逆置的字符串的字符数组 */ char a[N]; /* clrscr 函数定义在 conio.h 头文件中,所以 需要#include &conio.h& */ /* clrscr 函数的作用是进行清屏 */ /* 所谓清屏是指将已经显示在 DOS 窗口的 所有内容清除 */ clrscr(); /* 在 已 经 进 行 清 屏 的 DOS 窗 口 中 显 示 &Enter a string:&的提示信息 */ printf(&Enter a string:&); /* gets 函数定义在 stdio.h 头文件中,所以需 要#include & stdio.h & */ /* gets 函数的作用是接收用户从键盘上输入 字符串,然后放入参数 a 数组中 */ gets(a); /* 在 DOS 窗口中显示&The original string is:& 的提示信息 */ printf(&The original string is:&); /* puts 函数定义在 stdio.h 头文件中,所以需 要#include & stdio.h & */ /* puts 函数的作用是将参数 a 数组中的内容 输出到 DOS 窗口 */ puts(a); /* fun 函数的作用是将 a 数组中的字符串进 行逆置 */ fun(a); /* 输出换行符,可以使 DOS 窗口输出信息 的位置移动到下一行 */ printf(&\n&); /* 在 新 的 一 行 输 出 &The string after modified:&提示信息 */ printf(&The string after modified:&); /* 输出参数 a 数组中的内容,即进行逆置之 后的结果 */ puts(a); } } 分析: } main() { }for (i=1;___1___;i++) if(___2___) sum+=___3___; printf(&\nInput n: &); scanf(&%d&,&n); s=fun(n); printf(&\n\ns=%f\n&,s);要计算并输出 n (包括 n) 以内能被 3 或 7 整除的 所有自然数的倒数之和,可以设计总体思路如下: 由于计算 n (包括 n) 以内能被 3 或 7 整除的所有 自然数的倒数之和,所以我们可以使用循环一个一 个地检查从 1 到 n 范围中的这些数字是否能被 3 或 者 7 整除,如果可以整除,则计算当前循环检查的 数字 i 的倒数,i 的倒数计算方法如下:1.0/i。 由于计算的是倒数之和,所以程序中需要使用一 个变量 sum 保存倒数之和,这一个变量初始值应该 为 0.0, 然后每次循环的时候一旦发现当前检查的数 字 i 能被 3 或者 7 整除,就将 sum 变量的值加上数 字 i 的倒数, 然后将得到的和覆盖 sum 变量, sum 即 变量始终保存当前循环为止检查的能被 3 或 7 整除 的数字的倒数之和。当循环结束的时候,sum 变量 的值就是结果。 判断数字 i 能被 3 或者 7 整除可以使用取模运算 (%) 。根据 C 语言语法,取模运算就是取余数,例 如 5%2=3,因为 5 除以 2 得到的商为 1,余数为 3。 i 的倒数计算方法如下: 1.0/i, 为什么不写 1/i 呢? 根据 C 语言的语法,如果整除运算符(/)两个操作 数都是整数而不是实数的话,计算结果也是整数, 不管除法运算结果有没有小数部分,整除运算符的 结果只有整数部分。 例如 12/10=1, 而不是 1.2。 1.0/i 和 1/i 的区别在于 1.0 是实数类型(float、double) 而不是整数类型(int) ,由于 i 是整数类型,1.0/i 的运算结果为了使运算精度尽可能的得到保留,结 果将是实数类型, 即运算结果的小数部分得到保留。(4)题目: 请补充函数 fun,它的功能是:计算并输出 n(包 括 n)以内能被 3 或 7 整除的所有自然数的倒数之 和。 例如, 在主函数中从键盘给 n 输入 30 后, 输出为: s=1.226323。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在 fun 函数的横线上填入所编写的若干表达式或 语句。 #include &stdio.h& double fun(int n) { double sum=0.0; if(n&0&&n&=100) {而 1/i 的运算结果不保留小数部分, 因为 1 和 i 都是 整数类型。综上所述,我们希望 sum 变量保存倒数 之和,而倒数之和一定有小数部分,所以 sum 定义 为 double 类型,而第三处填空处必须填写 1.0/i,如 果填写 1/i,程序运算结果将是 0。 整个程序注解如下: #include &stdio.h& double fun(int n) { /* sum 用于累加符合条件的自然数的倒数之 和,所以初始化为 0.0 */ double sum=0.0; if(n&0&&n&=100) { /* 计算 n(包括 n)以内能被 3 或 7 整 除的所有自然数的倒数之和 */ /* 所以从第一个自然数 1 开始到 n 逐个 处理 */ for (i=1;i&=n;i++) /* i%3==0 表达式成立说明 i 能够被 3 整除 */ /* i%7==0 表达式成立说明 i 能够被 7 整除 */ if(i%3==0||i%7==0) /* 1.0/i 计算 i 的倒数,然后将 其累加到 sum 中 */ sum+=1.0/i; } } main() { printf(&\nInput n: &); scanf(&%d&,&n); s=fun(n); printf(&\n\ns=%f\n&,s); } (5)题目: 给定程序的功能是求二分之一的圆面积,函数通 过形参得到圆的半径,函数返回二分之一的圆面积 (注:圆面积公式为:S=3.14159*r*r,在程序中定 义的变量名要与公式的变量相同) 。 例 如 , 输 入 圆 的 半 径 值 : 19.527 , 输 出 为 s=598.950017。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在 fun 函数的横线上填入所编写的若干表达式或 语句。 #include &stdio.h& float fun ( float ___1___ ) { return 3.14159 * ___2___ /2.0; } main() { printf ( &Enter x: &);S=3.14159*r*r) ,所以第一处填空处填写&r&,而第 二处填空处根据圆面积公式为 S=3.14159*r*r 填写&r * r&。 整个程序注解如下: #include &stdio.h& float fun ( float r ) { /* 根据圆面积公式计算二分之一的圆面积 */ return 3.14159 * r * r } main() { /* 定义代表圆半径的变量 x */ /* 输出提示信息&Enter x: & */ printf ( &Enter x: &); /* 使用 x 变量接收键盘输入的圆半径 */ scanf ( &%f&, &x ); /* 输出计算结果 */ printf (& s = %f\n &, fun ( x ) ); } (6) 题目: 给定程序的功能是计算并输出下列级数的前 n 项 之和 Sn,直到 Sn 大于 q 为止,q 的值通过形参传 入。 Sn = 2/1 + 3/2 + 4/3 + …… + (n+1)/n 例如,若 q 的值为 50.0,则函数值为 50.416687。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在 fun 函数的横线上填入所编写的若干表达式或 语句。 #include &stdio.h& double fun( double q ) { n = 2; s = 2.0; while (s ___1___ q) { s=s+(double)(n+1)/n; ___2___ ; } printf(&n=%d\n&,n); ___3___ ; } main() { printf(&%f\n&, fun(50)); } 分析: 注解如下: #include &stdio.h& double fun( double q ) { /* 定义 s 变量保存 Sn 的值 */ n = 2; } } } } */ /2.0;/* 由于 Sn 计算公式的第一项是 2,所以代 表 Sn 之和的 s 变量初始值为 2.0 */ s = 2.0; /* 由于 Sn 计算直到 Sn 大于 q 为止, 所以进 行计算的循环设置以下循环条件 */ while (s &=q) { /* 计算 Sn 新的值 */ s=s+(double)(n+1)/n; /* 准备计算 Sn 中下一项,为下一次循 环作准备 */ n++; } printf(&n=%d\n&,n); /* 将计算得到的 Sn 合计值返回给 main 函数 main() { printf(&%f\n&, fun(50));(7)题目: 函数 fun 的功能是:统计长整数 n 的各个位上出现 数字 1、2、3 的次数,并通过外部(全局)变量 c1、 c2、c3 返回主函数。 例如, n= 时, 当 结果应该为: c1=3 c2=1 c3=2。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在 fun 函数的横线上填入所编写的若干表达式或 语句。 #include &stdio.h& int { c1 = c2 = c3 = 0; while (n) { switch(___1___) { case 1: c1++;___2___; case 2: c2++;___3___; case 3: c3++; } n /= 10; } main() { long n=L; fun(n); printf(&\nThe result :\n&); printf(&n=%ld c3=%d\n&,n,c1,c2,c3); 分析: 在程序设计方法中,有一个常用的技巧,这就是 如何获得一个整数的各个位数上的数字。方法就是 c1=%d c2=%d c1,c2,c3; void fun(long n)scanf ( &%f&, ___3___ ); printf (& s = %f\n &, fun ( x ) ); } 分析: 该程序求二分之一的圆面积,而圆面积公式为 S=3.14159*r*r, 所以 main 函数中需要输入圆的半径 r,然后在 fun 函数中使用圆面积公式计算圆面积的 二分之一。 在 main 函数中, 由于圆的半径长度可以带有小数 部分,所以代表圆的半径长度的变量必须是实数类 型,即 float 或者 double 类型。所以第三处填空处 应该填写&x,使用 x 变量接收 scanf 函数输入的圆 的半径长度。 由于题目要求&在程序中定义的变量名要与公式 的变量相同&,所以在 fun 函数中代表圆的半径长度 的变量必须使用 r 变量(因为圆面积公式为 运用取模(%)和整除(/)两种运算符。 两个整数进行整除运算得到的结果将只取整数部 分,如果有小数部分将被丢弃。所以通过将某个整 数整除 10 的倍数可以去掉低位的若干位的数字, 例 如将
整除 1000, 即得到 123114,所有低 于四位数的位数都被除去,而剩下了高位的数字。 如 果 我 想 得 到 123 , 既 可 以 进 行 以 下 运 算 : 。 再来看取模运算的作用。取模运算就是取余数, 例如 5%3=1,因为 5 除以 3 得到余数为 1。利用取 模运算我们可以得到一个整数的低位数字。例如 =0,即得到最低位的数字 0,而我们 如果需要得到低两位的数字,可以进行以下运算: 0=50。 综上所述,通过整除(/)运算可以高位数字,通 过取模(%)运算可以低位数字,如果我们配合使 用这两种运算,即可获得整数中任一位的数字。例 如我们想得到某个整数 n 的千位数字,我们可以先 进行 整除运算 ,然后再 进行取模运算 ,即进 行 n/1000%10 运算即可。或者先取模后整除也可以, 即 n%。例如取
的千位数字 4, 可以进行以下运算:00%10。 了解了以上程序设计的技巧之后,我们再回到题 目中。 为了统计长整数 n 的各个位上出现数字 1、 2、 3 的次数,我们可以使用循环逐个检查长整数 n 的 各个位数上的数字。那如何做到逐个检查长整数 n 的各个位数上的数字呢?我们可以使用取模(%) 和整除(/)两种运算实现以上思路。先使用 n%10 取得 n 变量中
最低位的数字,判读该数 字是否为数字 1、2、3。如果是 1,记录数字 1 个数 的 c1 变量加一。如果是 2,记录数字 2 个数的 c2 变量加一。如果是 3,记录数字 3 个数的 c3 变量加 一。然后将 n 值整除 10,得到的值覆盖 n 值,这样 就丢弃了最低位的数字,然后再次使用 n%10 取得 n 变量中
最低位的数字,然后再判断该数 是否为数字 1、2、3,反复以上过程,直至 n 等于 0 为止。 程序注解如下: #include &stdio.h& int { /* c1、c2、c3 分别表示数字 1、2、3 的个数, 所以初始值应该为 0 */ c1 = c2 = c3 = 0; /* 进行循环逐个检查每个位数上的数字是 否为数字 1、2、3 */ /* 类似于 while(n)的写法是 while(n!=0)的简 写方式 */ while (n) { /* 判断 n 最低位的数字是否为数字 1、 2、3 */ switch(n%10) { /* 判断 n 最低位的数字是否为数字 1 */ /* 注意要加 break 语句,否则即使 为数字 1,也会执行 case 2 的程序 */ case 1: c1++; } c1,c2,c3; void fun(long n) (8) 题目: } } main() { } 查过了 */ } 3 */ 2 *//* 判断 n 最低位的数字是否为数字 分析: case 2: c2++; /* 判断 n 最低位的数字是否为数字 case 3: c3++; /* 丢弃 n 的最低位, 因为最低位已经检 n /= 10; else e=d; 在题目的程序中首先定义了保存最大值的变量 max, 然后使用了 do-while 循环语句进行输入整数, long n=L; fun(n); printf(&\nThe result :\n&); printf(&n=%ld c3=%d\n&,n,c1,c2,c3); 以上程序中要注意的是第二处和第三处填空必须 填写 break 语句。如果第二处不加 break 语句,当 n%10 等于 1 的情况下,程序会执行 case 2 的部分, 虽然我们的意图是只执行 case 1 的部分。这是很多 考生容易犯错的地方。同理,第三处填空处也需要 填写 break 语句。如果不写 break 语句,当 n%10 等 于 2 的时候,将执行 case 2 部分的程序,c2 变量得 到加一, 但是没有 break 语句, 程序将继续执行 case 3 部分的程序,将 c3 变量也加一了,也不是我们希 望的,所以必须在第三处填空处加上 break 语句, 这样的话,c2 变量加一之后,执行 break 语句,就 直接执行 n/=10 这一句了。这才是我们所希望的。 c1=%d c2=%d 输入之后使用条件表达式将输入的整数和 max 进行 比较大小。如果输入的整数大于 max 的值,则将输 入的整数覆盖 max 的值,否则 max 的值不变, 这样 max 始终保持目前的最大值。反复进行以上过程, 直到输入的整数为 0,do-while 循环应该退出,这 时候 max 变量的值就是从键盘输入一组整数中最大 的值。这里注意的是,max 的初始值设置为 0,这 样才能在第一次和输入的整数比较大小的时候替换 成输入的整数,这是程序设计中的一个技巧,希望 考生能够自己体会一下。 程序注解如下: #include &stdio.h& #include &conio.h& #define N 100 main() { /* 定义一个足够大的数组存放从各个键盘 上输入的整数 */ int num[N]; int i=-1; /* max 存放最大值,初始值为 0 可以使 max 小于其他整数 */ /* 从而在与其他整数比较大小的时候被替 换成较大者,保持 max 变量为最大值 */ int max=0; /* clrscr 函数的作用是清除程序输出窗口的 所有已经显示的内容 */ /* clrscr 函数定义在 conio.h 中,所以需要 #include &conio.h& clrscr(); /* 输出提示信息&Input integer number:& */ printf(&\nInput integer number: \n&); /* 下面使用 do-while 循环反复输入整数和 max 进行比较大小 * /* 关键在于 max 的值一直被较大的整数替 换 */ do { i++; i++; printf(&num[%d]=&,i); scanf(&%d&,___1___); max= ___2___ num[i] : }while(___3___); printf(&max=%d\n&, max); /* 输出提示信息:&num[i]= &,其中 i 的值是由 i 变量决定的 */ printf(&num[%d]=&,i); /* 使用 scanf 函数输入整数,并且存放 在 num 数组中 */ scanf(&%d&,&num[i]); /* 将输入的整数与 max 当前值比较大 请补充 main 函数, 该函数的功能是: 从键盘输入 一组整数,使用条件表达式找出最大的整数。当输 入的整数为 0 时结束。 例如,当输入 1 2 3 5 4 0 时,最大的数为 5。 注意:部分源程序如 blank.c 给出。 仅在横线上填入所编写的若干表达式或语句,勿 改动函数中的其他任何内容。 #include &stdio.h& #include &conio.h& #define N 100 main() { int num[N]; int i=-1; int max=0; clrscr(); printf(&\nInput integer number: \n&); do { 题目要求使用条件表达式找出最大的整数,所谓 条件表达式就是指 a&b?c:d,根据 C 语言的语法, a&b?c:d 整个表达式表示根据 a&b 条件是否成立判 断整个表达式的值为 c 还是 d,如果 a&b 成立,则 整个表达式的值为 c,否则为 d。所以 e=a&b?c:d 整 个表达式是以下语句的简写方式: if (a&b) e=c; 小 */ /* 如果 max&num[i], max 的值被 num[i] 替换,也就是被输入的整数替换 */ /* 否则还是使用 max 原有的值替换, 也 就是值保持不变 */ max= max&num[i]? num[i] : }while(num[i]!=0); /* 由于题目要求当输入的整数为 0 时结束, 所以循环条件为 num[i]!=0 */ /* 输出最大值 max */ printf(&max=%d\n&, max); } (9) 题目: 给定程序的功能是分别统计字符串中大写字母和 小写字母的个数。 例如,给字符串 ss 输入:AaaaBBb123CCccccd, 则输出结果应为:upper=5,lower=9。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在横线上填入所编写的若干表达式或语句。 #include &stdio.h& void fun ( char *s, int *a, int *b ) { while ( *s ) { if ( *s &= 'A' && *s &= 'Z' ) ___1___ ; if ( *s &= 'a' && *s &= 'z' ) ___2___ ; s++; } } main( ) { char int s[100]; upper = 0, lower = 0 ;希望在 fun 函数中统计大小写字母的过程中 upper、 lower 变量的值得到改变,退出 fun 函数直接输出 upper、 lower 变量就可以看到大小写字母的个数了。 那如何解决这种问题呢?根据 C 语言的语法,以 上问题可以通过使用指针解决。以上的问题是由于 参数传递方式为传值方式所导致的,可以通过将传 入的参数改为指针类型改变参数传递方式为传地址 方式。所以 fun 函数的函数头为以下: void fun (char *s, int *a, int *b ) 分别对应 upper、lower 的 a 变量和 b 变量为指针 类型,相应的 main 函数中传入 fun 函数的参数为 &upper,&lower。这样在 fun 函数中操作 a、b 指针 才能达到预期效果。 fun 函数中, 指针所指向的 在 a 内存地址中存放了记录大写字母个数的值,而 b 指 针所指向的内存地址中存放了记录小写字母个数的 值。在 fun 函数中,我们通过*a、*b 引用 a、b 指针 所指向的内存地址中存放的大、 小写字母个数的值, 当发现大写或者小写字母的时候将*a 或者*b 加一。 退出 fun 函数的时候,形式参数 a、b 由于超出作用 域而消失,但是它们指向的内存地址中的值还保留 着, 这些值在 main 函数中可以分别通过 upper、 lower 引用,从而解决了函数参数退出函数之后恢复原值 的问题。 程序注解如下: #include &stdio.h& /* s 参数表示传入的字符串,a、b 参数表示大写 字母和小写字母的个数 */ /* s 是一个指针,指向传入的字符串的第一个字 母 */ void fun ( char *s, int *a, int *b ) { /* while(*s)是 while(*s!=’ )的简写方式 */ \0’ /* s 指针指向的字母不为’\0’ ,就是说循环 检查到字符串结束符才退出循环 */ while ( *s ) { /* 判断 s 指针指向的字母是否是大写字 母,如果是就把*a 加一 */ if ( *s &= 'A' && *s &= 'Z' ) lower = %d\n&, (*a)++ ; /* 判断 s 指针指向的字母是否是小写字 母,如果是就把*b 加一 */ if ( *s &= 'a' && *s &= 'z' ) (*b)++ ; /* s 指针往后移动一个字母位置,准备 判断下一个字母是否为大小写字母 */ s++; } } main( ) { char s[100]; /* upper、lower 变量分别记录大写字母和小 写字母的个数 */ int upper = 0, lower = 0 ; printf( &\nPlease a string : & ); /* gets 函数定义在 stdio.h 中,所以需要 #include &stdio.h& */ /* gets 函数接收键盘输入的字符串,将其放 入参数 s 数组中 */ } 分析: }gets ( s ); /* 取存放 upper 变量、lower 变量的地址, 将其作为指针传入 fun 函数 */ fun ( s, & upper, &lower ); /* 输出在 fun 函数中改变的 upper、lower 变 量,也就是大小写字母个数 */ printf( &\n upper = %d upper,lower ); lower = %d\n&,(10) 题目: 请补充 main 函数, 该函数的功能是: 从键盘输入 3 个整数,然后找出最大的数并输出。 例如,输入:12,45,43,输出为 45。 注意:部分源程序如 blank.c 给出。 仅在横线上填入所编写的若干表达式或语句,勿 改动函数中的任何内容。 #include &stdio.h& #include &conio.h& main() { int a,b,c, clrscr(); printf(&\nInput three numbers:\n&); scanf(&%d,%d,%d&,&a,&b,&c); printf(&The are:%d,%d,%d\n&,a,b,c); if (a&b) ___1___; else ___2___; if(max&c) ___3___; printf(&max=%d\n&,max); three numbersprintf( &\nPlease a string : & ); gets ( s ); fun ( s, & upper, &lower ); printf( &\n upper = %d ___3___ ); } 分析: 题目要求统计字符串中大写字母和小写字母的个 数,所以在 main 函数中使用 gets 函数接收从键盘 上输入的字符串 s,然后将 s 传入 fun 函数,在 fun 函数中统计传入的字符串 s 中大写字母和小写字母 的个数。 这里需要注意的是在 main 函数中 upper、lower 变量分别记录大写字母和小写字母的个数。这两个 int 类型的变量要在 fun 函数中统计字符串 s 中大写 字母和小写字母的个数的时候进行增加的,然后退 出 fun 函数回到 main 函数中 upper、 lower 变量应该 分别是大写字母和小写字母的个数。然而,根据 C 语言的语法, 普通 int 类型的变量的值在某函数 (例 如 fun 函数)中进行变化之后退出该函数,在 main 函数中该变量将丢失在那个函数(例如 fun 函数) 的变化而直接恢复到进入函数(例如 fun 函数)之 前的值,也就是说在函数(例如 fun 函数)的变化 都是无效的。这显然不是我们所希望的,因为我们程序要求从键盘输入 3 个整数,然后找出最大的 数并输出。 实现思路如下: 首先判断前面两个整数, 取两者较大者保存在变量 max 中, 然后将 max 保存 的较大者与第三个整数进行比较大小,同样也将两 者较大者保存在 max 变量中, 最后 max 变量记录的 值就是 3 个参加比较大小的整数中最大的一个整 数。 程序注解如下: #include &stdio.h& #include &conio.h& main() { int a,b,c, /* clrscr 函数的作用是清屏, 将输出窗口的已 显示内容全部清除 */ /* clrscr 定义在 conio.h 中, 所以需要#include &conio.h& */ clrscr(); /* 在输出窗口上输出提示信息&Input three numbers:& */ printf(&\nInput three numbers:\n&); /* 从键盘上输入 3 个整数, 按照顺序赋值给 a、b、c */ /* 由于指定了&%d,%d,%d&输入格式,输入 的时候三个整数必须以逗号分隔 */ /* 例如输入 12、45、43 三个整数,输入格 式如下:12,45,43 */ /* 三个整数输入之后按回车键即可完成整 个输入过程 */ scanf(&%d,%d,%d&,&a,&b,&c); /* 将输入的三个整数输出 */ printf(&The are:%d,%d,%d\n&,a,b,c); /* 将前两个整数进行比较,将较大者放入 max 变量中 */ if (a&b) max=a; else max=b; /* 将前两个整数的较大者也就是 max 与第 三个整数进行比较大小 */ /* 较大者放入 max 变量中 */ if(max&c) max=c; /* 输出三个整数中的最大值 */ printf(&max=%d\n&,max); } (11)题目: 给定程序中,函数 fun 的功能是:把形参 s 所指 字符串中下标为奇数的字符右移到下一个奇数位 置,最右边被移出字符串的字符绕回放到第一个奇 数位置,下标为偶数的字符不动(注:字符串的长 度大于等于 2) 。 例如,形参 s 所指的字符串为:abcdefgh,执行 结果为:ahcbedgf。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在 fun 函数的横线上填入所编写的若干表达式或 语句。 #include &stdio.h& void fun(char *s) { int i, n, n=0; for(i=0; s[i]!='\0'; i++) n++; if(n%2==0) k=n-___1___ ; else k=n-2; c=___2___ ; for(i=k-2; i&=1; i=i-2) s[i+2]=s[i]; s[1]=___3___ ; } main() { char s[80]=&abcdefgh&; printf(&\nThe original string is : %s\n&,s); fun(s); printf(&\nThe result is : %s\n&,s); } 分析: three numbers题目要求在 fun 函数中把形参 s 所指字符串中下 标为奇数的字符右移到下一个奇数位置,最右边被 移出字符串的字符绕回放到第一个奇数位置,下标 为偶数的字符不动。要实现以上功能,我们可以有 以下思路: 先计算字符串中包含的字符个数,然后将最右边 可能被移出字符串的字符保存在另外一个变量 c 中,然后从字符串右边第一个奇数位置的字符开始 往左边循环,循环体中将奇数位置的字符覆盖右边 临近的奇数位置的字符,当到了字符串最左边的时 候循环结束,将预先保存在 c 变量中的右边被移出 字符串的字符覆盖左边第一个奇数位置的字符即 可。 这里需要注意的是字符串中第一个位置的下标为 0, 而不是 1。 这是因为字符串也是一个 char 类型的 数组,而数组在 C 语言中第一个元素的下标是 0, 所以题目中所指的字符串第一个字符的下标是 0。 以上所讲的思路为什么不从左边开始向右边循环 呢?关键的问题在于如果从左边开始把下标为奇数 的字符右移到下一个奇数位置的话,程序将出现逻 辑混乱。举一个具体的例子,例如字符串为 &abcdefgh&,第一个奇数位置的字符为&b&,第二个 奇数位置的字符为&d&,第三个奇数位置的字符为 &f&,依次类推。当程序从左边开始把下标为奇数的 字符右移到下一个奇数位置的时候,我们先从第一 个奇数位置开始。 当第一个奇数位置的字符&b&覆盖 第二个奇数位置的字符&d&之后, 我们想把原来第二 个奇数位置的字符&d& 右移到下一个奇数位置的时 候发现它已经被第一个奇数位置的字符&b&覆盖了, 处理不方便。所以我们选择从右边到左边的处理方 式。 程序注解如下: #include &stdio.h& void fun(char *s) { int i, n, /* n 为存放字符串 s 字符个数的变量,初始值 为 0 */ n=0; /* 计算字符串 s 包含的字符个数,得到的个数 存放在 n 变量中 */ for(i=0; s[i]!='\0'; i++) n++; /* 计算字符串中最后一个奇数位置的下标 */ /* 如果字符串字符个数为偶数, 最后一个奇数 位置的下标 k 为个数减一 */ /* 如果字符串字符个数为奇数, 最后一个奇数 位置的下标 k 为个数减二 */ if(n%2==0) k=n-1 ; else k=n-2; /* 将最后一个奇数位置上的字符先保存在 c 变 量中,准备开始循环 */ c= s[k] ; /* 从右边最后一个奇数位置开始, 将前一个奇 数位置的字符覆盖自己 */ for(i=k-2; i&=1; i=i-2) s[i+2]=s[i]; /* 以上循环结束后只有原来最后一个奇数位 置的字符被丢失 */ } } } }/* 程序使用预先保存在 c 变量的值回放到第一 个奇数位置 */ s[1]= main() { char s[80]=&abcdefgh&; printf(&\nThe original string is : %s\n&,s); fun(s); printf(&\nThe result is : %s\n&,s);(2)题目: 请补充 fun 函数,该函数的功能是将字符串 tt 中 的大写字母都改为对应的小写字母, 其他字符不变。 例如,若输入&Are you come from Sichuan?&,则 输出&are you come from sichuan?&。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在 fun 函数的横线上填入所编写的若干表达式或 语句。 #include &stdio.h& #include &string.h& #include &conio.h& char *fun(char tt[]) { for(i=0;tt[i];i++) { if((tt[i]&='A')&&(___1___)) ___2___; } return (___3___); main() { char tt[81]; printf(&\nPlease enter a string: &); gets(tt); printf(&\nThe result string is: \n%s&,fun( tt ));分析: 题目要求将字符串 tt 中的大写字母都改为对应的 小写字母,其他字符不变。这里主要的问题是如何 实现大写字母转化成小写字母。 在程序设计方法中, 大小写字母的互相转换可以使用以下技巧: 在 ASCII 码表中,大写字母&A&的 ASCII 码值为 65,大写字母&B&的 ASCII 码值为 66,大写字母&C& 的 ASCII 码值为 67, 后面的大写字母的 ASCII 码值 依次类推,大写字母在 ASCII 码表中是按顺序排列 的,最后的&Z&的 ASCII 码值为 90。小写字母&a&的 ASCII 码值为 97, 小写字母&b&的 ASCII 码值为 98, 小写字母&c&的 ASCII 码值为 99,后面的小写字母 的 ASCII 码值依次类推,小写字母在 ASCII 码表中 也是按顺序排列的, 最后的&z&的 ASCII 码值为 122。 根据以上情况,我们可以发现所有对应的大写字 母和小写字母 ASCII 码相差 32。例如&B&和&b&的 ASCII 码相差 32, &K&和&k&的 ASCII 码相差 32, &E& 和&e&的 ASCII 码也是相差 32。利用这种特性和 C 语言的语法,如果要将大写字母都改为对应的小写 字母,只要将该字符加上 32 即可。同理,如果要将 小写字母都改为对应的大写字母,只要将该字符减 去 32 即可。例如以下程序就可以将字符&D&转化成 &d&然后输出。 main() { char c1 = 'D'; char c2 = c1 + 32; printf(&%c&,c2); } 程序注解如下: #include &string.h& #include &conio.h& char *fun(char tt[]) { /* 开始循环逐一检查 tt 数组中每一个字符 */ /* for(i=0;tt[i];i++)是 for(i=0;tt[i]!= '\0';i++)的简 写方式 */ for(i=0;tt[i];i++) { /* 如果 tt 数组当前元素的 ASCII 码在'A' 与'Z'之间,说明是大写字母 */ /* 如果是大写字母,就加上 32 转换成对应 的小写字母 */ if((tt[i]&='A')&&( tt[i]&='Z')) tt[i]+=32; } /* 由于 fun 函数返回类型为 char *类型 */ /* 再结合 main 函数中输出调用 fun 函数的返 回值是转化之后的字符串 */ /* 所以判断 fun 函数应该返回 tt 数组 */ /* tt 虽然是数组名称,但是 C 语言语法规定数 组名同时也是指针 */ /* C 语言语法规定数组名代表的指针指向数组 第一个元素 */ return (tt); } main() { char tt[81]; /* 在输出窗口显示提示信息 &Please enter a string: & */ printf(&\nPlease enter a string: &); /* 使用 gets 函数接收键盘输入的字符串, 输入 的字符串存入 tt 数组 */ /* gets 函数定义在 stdio.h 中, 所以需要#include &stdio.h& */ gets(tt); /* 输出结果 */ printf(&\nThe result string is: \n%s&,fun( tt )); } (13)题目: 请补充 fun 函数,该函数的功能是判断一个数是 否为素数。该数是素数时,函数返回字符串:yes! , 否则函数返回字符串:no! ,并在主函数中输出。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容,仅在 fun 函数的横线上填入所编写的若干表达式或 语句。 #include &conio.h& #include ___1___ { int i, m=1; for(i=___2___;i&n;i++) if (___3___) { m=0; } if(m==1&&n&1) return(&yes!&); else return(&no!&); } main() { int k=0; &stdio.h&/* m 初始值为 1 */ m=1; /* 从 2 开始至 n-1 逐一检查在这范围之内的整 数是否可以被 n 整除 */ for(i=2;i&n;i++) /* 当发现有整数可以被 n 整除的时候 */ if (n%i==0) { /* 当发现有整数可以被 n 整除的时 候,n 不符合素数的定义 */ /* 所以没有必要继续检查其他的整 数了,所以退出循环 */ /* m 等于 0 就代表 n 不是素数 */ m=0; } /* 开始检查以上循环的检查情况 */ if(m==1&&n&1) /* m 等于 1 的情况代表在循环中没有发现 有整数可以被 n 整除 */ /* 也就是说 n 符合素数的定义, 它是一个 素数 */ return(&yes!&); else return(&no!&); } main() { int k=0; /* clrscr 函数用于清除输出窗口中已经显示的 内容 */ /* clrscr 函数定义在 conio.h , 所以需要#include &conio.h& */ clrscr(); /* 在输出窗口中输出提示信息&Input:& */ printf(&Input:&); /* 从键盘接收输入值, 使用 k 变量保存输入值 */ scanf(&%d&,&k); /* 在输出窗口中输出 fun 函数的判断结果 */ printf(&%s\n&, fun(k)); } 以上程序运用了程序设计方法中的一个常用技 巧。在下列程序片断中,为了判断 for 循环中处理 的结果,程序预先设置了 m 变量为 1,当 for 循环 中发生了某些事情(下列程序段中发生了发现从 2 至 n-1 之间范围的整数存在有整数可以被 n 整除的 情况)的时候将 m 变量设置为其他值(下列程序段 将 m 设置为 0) 。当 for 循环结束之后,程序检查 m 变量的值是否和进入 for 循环之前的值是否相同, 如果不同,则根据 m 的当前值判断 for 循环中发生 了哪些事情。如果 m 变量的值在 for 循环中没有发 生改变, 则说明可能要发生的情况并没有发生改变。 这个程序设计技巧经常被使用,希望考生自己体会 并消化吸收。 m=1; for(i=2;i&n;i++) if (n%i==0) { m=0;clrscr(); printf(&Input:&); scanf(&%d&,&k); printf(&%s\n&, fun(k)); } 分析: 该题的核心在于如何判断一个数是素数。所谓素 数是这样的整数,它除了能表示为它自己和 1 的乘 积以外,不能表示为任何其它两个整数的乘积。例 如, 15=3*5, 所以 15 不是素数; 又如, 12=6*2=4*3, 所以 12 也不是素数。另一方面,13 除了等于 13*1 以外,不能表示为其它任何两个整数的乘积,所以 13 是一个素数。 了解素数的概念之后,我们可以有以下思路用于 判断某一个整数是否为素数: 给定一个整数 n,我们可以从 2 开始至 n-1 逐一 检查在这范围之内的整数是否可以被 n 整除。如果 可以,那说明整数 n 除了能表示为它自己和 1 的乘 积以外,还能表示为其他两个整数的乘积,所以整 数 n 不是素数。如果从 2 开始至 n-1 范围之内的所 有整数都不可以被 n 整除,那说明整数 n 符合素数 的定义,所以整数 n 是一个素数。 那从 2 开始至 n-1 逐一检查在这范围之内的整数 是否可以被 n 整除呢?一方面我们可以循环进行, 另外判断两个整数是否可以被整除可以使用取模 (%)运算。例如 10%5 等于 0,那么 10 可以整除 5。11%5 等于 6,不等于 0,那么 11 不可以整除 5。 程序注解如下: #include #include 数 */ char *fun( int n ) { int i, /* m 作为一个标记,用于记录是否存在可以被 整除的数字 */ &conio.h& &stdio.h&/* fun 函数的功能是判断传入的 n 参数是否为素
} if(m==1&&n&1) return(&yes!&); else return(&no!&); (14)题目: 请补充 fun 函数,该函数的功能是:依次取出字 符串中所有小写字母,形成新的字符串,并取代原 字符串。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在 fun 函数的横线上填入所编写的若干表达式或 语句。 #include &stdio.h& #include &conio.h& void fun(char *s) { int i=0; char *p=s; while(___1___) { if(*p&='a' && *p&='z') { s[i]=*p; ___2___; } p++; } s[i]=___3___; } main() { char str[80]; clrscr(); printf(&\nEnter a string :&); gets(str); printf(&\n\nThe string is : \%s\n&,str); fun(str); printf(&\n\nThe string of changing is : \%s\n&,str); } 分析: 题目要求在 fun 函数中依次取出字符串中所有小 写字母,形成新的字符串,并取代原字符串。要完 成以上要求,必须知道如何判断字符串中的字符为 小写字母。 我们首先看一下 ASCII 码表,该表全称是美国标 准 信 息 交 换 码 (American Standard Code for Information Interchange)。在这张表中,小写字母&a& 的 ASCII 码值为 97,小写字母&b&的 ASCII 码值为 98,小写字母&c&的 ASCII 码值为 99,后面的小写 字母的 ASCII 码值依次类推,最后的&z&的 ASCII 码值为 122。所有的小写字母在 ASCII 码表中是按 顺序排列的,它们在 ASCII 表的码值开始于 97,结 束于 122。 而根据 C 语言的语法,判断两个字符之间的大小 实际上是比较两个字符在 ASCII 表中的码值大小。 例如&c&字符大于&b&字符,因为&c&的 ASCII 码值为98,&c&的 ASCII 码值为 99,&c&的 ASCII 码值大于 &c&的 ASCII 码值。使用 C 语言描述就是'c'&'b'这个 表达式成立。 综上所述,判断某个字符是否为小写字母只要判 断该字符的 ASCII 码值是否在&a&和&z&之间即可。 如果在这范围之内,该字符就是小写字母,否则不 是 题目要求在 fun 函数中依次取出字符串中所有小 写字母,形成新的字符串,并取代原字符串。要完 成以上要求,我们还需要使用指针从字符串第一个 字符开始往后移动,逐一判断指针所指的字符是否 为小写字母,如果是小写字母,则将其放入该字符 串的前面部分。例如字符串 s 为&AbGhijk&,指针 p 初始化的时候指向字符串 s 的第一个字母&A&。 字母 &A&不是小写字母,指针 p 移动到&b&字符,发现它 是一个小写字母, 就将&b&字符覆盖第一个字母&A&, 指针往后移动指向&G&。&G&字符不是小写字母,指 针继续往后移动指向&h&。&h&字母为小写字母,程 序 将 &h&覆 盖 原 来 &b&的 位 置 , 即 字符 串 s 变 为 &bhGhijk&。指针 p 继续往后移动,重复以上过程, 最后字符串 s 变为&bhijkjk&。 经过以上处理之后,程序需要将最后多余的字母 去掉。通过在我们需要的最后一个字母后面设置字 符串结束标记'\0'就可以截断原有的字符串。程序将 &bhijk&后面的&j&字母改为字符串结束标记'\0'即可 形成新的字符串,并取代原字符串。 程序注解如下: #include &stdio.h& #include &conio.h& void fun(char *s) { /* i 变量指示小写字母插入字符串 s 的位置, 初 始值为 0,表示第一个位置 */ int i=0; /* 初始化 p 指针,将其指向 s 字符串第一个字 符 */ char *p=s; /* while(*p)是 while(*p!= '\0')的简写方式 */ /* while 循环中 p 指针不断往后移动, 逐一检查 所指字符是否是小写字母 */ while(*p) { /* 判断 p 指针所指向的字符是否是小写字 母 */ /* 判断依据是 p 指针所指向的字符的 ASCII 码值是否在'a'和'z'之间 */ if(*p&='a' && *p&='z') { /* 是小写字母,则将其放入字符串 s 的前面部分,位置由 i 决定 */ s[i]=*p; /* i 加一,为下一个小写字母指示在 字符串 s 中的存放位置 */ i++; } /* p 指针往后移动,指向下一个字符位置 的字符 */ p++; } /* 在提取出来的小写字母的后面加上字符串结束标记'\0' */ /* 这样才能形成新的字符串, 并取代原字符串 */ s[i]='\0'; } main() { char str[80]; /* clrscr 函数用于清除输出窗口中已经显示的 内容 */ /* clrscr 函数定义在 conio.h , 所以需要#include &conio.h& */ clrscr(); /* 在输出窗口输出提示信息&Enter a string :& */ printf(&\nEnter a string :&); /* 使用 gets 函数接收键盘输入的字符串, 输入 的字符串存入 str 数组 */ /* gets 函数定义在 stdio.h 中, 所以需要#include &stdio.h& */ gets(str); /* 将键盘输入的字符串输出在输出窗口 */ printf(&\n\nThe string is : \%s\n&,str); /* 将键盘输入的字符串传入 fun 函数进行处理 */ fun(str); /* 将 fun 函数处理结果输出在输出窗口 */ printf(&\n\nThe string of changing is : \%s\n&,str); } (15) 题目: 给定程序的功能是判断字符 ch 是否与串 str 中的 某个字符相同;若相同,什么也不作,若不同,则 插在串的最后。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在 fun 函数的横线上填入所编写的若干表达式或 语句。 #include &stdio.h& #include &string.h& void fun(char *str, char ch ) { while ( *str && *str != ch ) str++; if ( *str ___1___ ch ) { str[0] = ___2___ = 0; } } main() { char s[81], printf( &\nPlease enter a string:\n& ); gets ( s ); printf (&\n Please enter the character to search : & ); c = getchar(); fun(___3___) ; printf( &\nThe result is %s\n&, } 分析: s); 题目要求判断字符 ch 是否与串 str 中的某个字符 相同;若相同,什么也不作,若不同,则插在串的 最后。我们可以使用指针在字符串中从第一个字符 开始向后面移动,程序检查指针在移动过程中所指 向的字符是否与字符 ch 相同, 如果发现有不同的字 符则将指针不断往后移动。这样的结果分为以下两 种: (1)在 str 字符串后面发现和 ch 字符相同的字符, 那么停止往后移动指针,进入判断 if (*str != ch), 由于 ch 字符与 str 指针当前指向的字符相同,则 if 语句的条件不能得到满足,fun 函数执行结束,体 现了题目关于&若相同,什么也不作&的要求。 (2) 在 str 字符串后面一直没有发现和 ch 字符相 同的字符, 那么指针 str 一直往后移动到字符串的结 束标记'\0'。此时 str[0]表示的是字符串最后的'\0'。 设置 str[0]为 ch 字符, 从而将 ch 字符插入原字符串 的最后。设置 str[1]为字符串结束标记'\0',从而声 明了新的字符串的最后位置。 这里需要注意以下 C 语言的语法: 数组名同时也是指向数组第一个元素的指针。如 果这个指针在数组中移动,该指针所指向的数组元 素则成为新数组的第一个元素。 为了说明这个问题, 可以看以下程序。 void func(char * b) { printf(&str=%s\n&,b); b++; printf(&str=%s\n&,b); b[0]= 'k'; printf(&str=%s\n&,b); } main() { char a[]=&abcd&; func(a); } 在 func 函数中两次输出结果如下: str=abcd str=bcd str=kcd 以上程序在 func 函数中将 b 指针往后移动一个字 母, b 参数代表 main 函数的 a 数组名的,所以此 而 时 b 指向的字符串为&bcd&, b[0]= 'b', b[0]= 'c', b[0]= 'd'。执行 b[0]= 'k';之后,b 向的字符串为&kcd&。 这里掌握的原则就是指针同时可以理解为数组 名,数组名同时也可以理解为指针,这正是 C 语言 灵活的地方。 程序注解如下: #include &stdio.h& #include &string.h& /* fun 函数判断字符串 str 中是否存在某一个字符 与字符 ch 相同 */ /* 若存在相同,什么也不作。若不存在,则将字 符 ch 插在字符串 str 的最后 */ void fun(char *str, char ch ) { /* while(*str && *str!=ch)相当于 while(*str!='\0' && *str!=ch) */ /* 在 str 中找不到和字符 ch 相同的字符,则指 向字符串的 str 指针往后移动 */ } } & ); }while ( *str && *str != ch ) str++; /* 在 str 中找不到和字符 ch 相同的字符, ch 将 字符放入字符串的最后 */ if ( *str != ch ) { /* 经过以上移动, 指针已经移动到字符 str 串的最后位置的结束标记位置 */ /* 例如,字符串为&abc&,此时 str 指向字 符 c 后面的'\0' */ /* 由于数组名同时也是指针,所以 str[0] 表示的是&abc&最后的'\0' */ /* 将 ch 字符覆盖字符串&abc&最后的'\0' */ str[0] = /* 字符串结束标记'\0'也可以用 0 来表示, 两者值是一样的 */ /* 在 ch 字符后面设置字符串结束标记'\0' 的值,切断后面字符,形成新串 */ str[1] = 0; } main() { char s[81], printf( &\nPlease enter a string:\n& ); gets ( s ); printf (&\n Please enter the character to search : /* getchar 函数用于从键盘上输入一个单一的 字符,输入的字符被返回给 c */ c = getchar(); fun(s, c) ; printf( &\nThe result is %s\n&, (16) 题目: 请补充 fun 函数,该函数的功能是:判断一个年 份是否为闰年。 例如,1900 年不是闰年,2004 是闰年。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在 fun 函数的横线上填入所编写的若干表达式或 语句。 #include &stdio.h& #include &conio.h& int fun(int n) { int flag=0; if (n % 4==0) { if (___1___) flag=1; } if (___2___) flag=1; return ___3___; main() { clrscr(); printf(&Input the year:&); } } s); 除*/scanf(&%d&,&year); if (fun(year)) printf(&%d is a leap year.\n&,year); else printf(&%d is not a leap year.\n&,year); }分析: 题目要求在 fun 函数中判断传入的参数年份是否 为闰年, 所以关键是如何判断一个年份是否为闰年。 目前常用的判断方法有以下一种。 一个年份 n 是否为闰年必须符合下面两条件之 一: (1)能被 4 整除,但不能被 100 整除 (2)能被 400 整除 以上两个条件使用 C 语言描述就是 (1)n % 4 == 0 && n%100 !=0 (2)n % 400 == 0 程序注解如下: #include &stdio.h& #include &conio.h& int fun(int n) { /* 设置 flag 为 0,如果最后 flag 变为 1 则说明 年份 n 为闰年 */ int flag=0; /* 判断年份 n 是否满足条件之一: 能被 4 整除, 但不能被 100 整除 */ if (n % 4==0) { if (n % 100 != 0) flag=1; } /* 判断年份 n 是否满足条件之二: 能被 400 整 if (n % 400 == 0) flag=1; main() { /* clrscr 函数用于清除输出窗口中已经显示的 内容 */ /* clrscr 函数定义在 conio.h , 所以需要#include &conio.h& */ clrscr(); /* 在输出窗口输出提示信息&Input the year:& */ printf(&Input the year:&); /* 输入年份,保存在 year 变量中 */ scanf(&%d&,&year); /* 从以下程序可以看出,fun 函数返回值不等 于 0 的时候表示 year 为闰年 */ /* if (fun(year))是 if (fun(year)!=0)的简写方式*/ /* leap year 中文为闰年的意思 */ if (fun(year)) printf(&%d is a leap year.\n&,year); else printf(&%d is not a leap year.\n&,year); (17) 题目: 给定程序的功能是将 n 个人员的考试成绩进行分 段统计,考试成绩放在 a 数组中,各分段的人数存 到 b 数组中:成绩为 60 到 69 的人数存到 b[0]中, 成绩为 70 到 79 的人数存到 b[1],成绩为 80 到 89 的人数存到 b[2], 成绩为 90 到 99 的人数存到 b[3], 成绩为 100 的人数存到 b[4], 成绩为 60 分以下的人 数存到 b[5]。 例如,当 a 数组中的数据是:93、85、77、68、59、 43、94、75、98。调用该函数后,b 数组中存放的 数据应该是:1、2、1、3、0、2。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在 fun 函数的横线上填入所编写的若干表达式或 语句。 #include &stdio.h& void fun(int a[], int b[], int n) { for (i=0; i&6; i++) b[i] = 0; for (i=0; i& ___1___; i++) if (a[i] & 60) b[5]++; ___2___ b[(a[i]- 60)/10]++; } main() { int i, a[100]={ 93, 85, 77, 68, 59, 43, 94, 75, 98}, b[6]; fun(___3___, 9); printf(&the result is: &); for (i=0; i&6; i++) printf(&%d &, b[i]); printf(&\n&); } 分析: 程序思路如下: 在 fun 函数中使用循环逐一检查 a 数组中的成绩, 然后根据成绩把 b 数组对应的元素加一。例如 a 数 组中某元素的成绩为 88,则将 b[2]加一,因为根据 题目说明成绩为 80 到 89 的人数存放在 b[2]。 程序注解如下: #include &stdio.h& void fun(int a[], int b[], int n) { /* 各分数段的人数存到 b 数组中,所以先将 b 数组各个元素初始化为 0 */ for (i=0; i&6; i++) b[i] = 0; /* 开始循环统计 a 数组中各个分数段的人数 */ /* 因为从 0 开始,所以 n 是循环终止条件*/ for (i=0; i&n; i++) /* 由于成绩为 60 分以下的人数存到 b[5], 所以发现一个就把 b[5]加一 */ if (a[i] & 60) b[5]++; else /* 60 分以上使用以下公式放入合适的 b 数组元素中 */ b[(a[i]- 60)/10]++; } main() { int i, a[100]={ 93, 85, 77, 68, 59, 43, 94, 75, 98}, b[6]; /* 从 fun 函数程序可以看出 fun 函数第一个参 数为存放考试成绩的 a 数组 */ /* 可以看出 fun 函数第二个参数为存放各分数 段的人数的 b 数组 */ /* fun 函数第三个参数为 a 数组中的元素个数, 这里为 9 */ fun(a, b, 9); printf(&the result is: &); /* 输出各个分数段的人数 */ for (i=0; i&6; i++) printf(&%d &, b[i]); printf(&\n&);} (18)题目: str 为一个字符序列。请补充 fun 函数,该 函数的功能是: 查找 str 中值为 x 的元素, 返回找到 值为 x 的元素个数,并把这些值为 x 的元素下标依 次保存在数组 bb 中。 例如,在&abcdefahij&中查找‘a’ ,结果为: 2 个‘a’ ,下标依次为 0、6。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任 何内容,仅在 fun 函数的横线上填入所编写的若干 表达式或语句。 #include &stdio.h& #include &conio.h& #define N 20 int bb[N]; int fun(char *str,char ch) { int i=0,n=0; char t= char *p= while ( *p ) { if(___1___) ___2___; p++; i++; } return ___3___; } main() { char str[N]; int i,j,n; clrscr() ; printf(&******* string*******\n &); gets(str); printf(&******* The Original string *******\n&); puts(str); } Input the original 同 */ 分析: } *******\n&); is: %d\n&,n); *******\n&);printf(&******* scanf(&%c&,&ch); n=fun(str,ch);Inputcharacterprintf(& \nThe number of character printf(&******* The suffix of character for(i=0;i&n;i++) printf(& %d &,bb[i]);题目要求查找 str 字符串中值为 x 的元素, 返回找 到值为 x 的元素个数,并把这些值为 x 的元素下标 依次保存在数组 bb 中。 程序注解如下: #include &stdio.h& #include &conio.h& #define N 20 /* bb 数组中存放 str 字符串中和 ch 字符相同的字 符的下标 */ /* bb 数组可以容纳 20 个元素,这里只要个数大 小足够大就可以了 */ int bb[N]; int fun(char *str,char ch) { /* i 是记录 p 指针所指字符在 str 字符串中的下 标 */ /* str 是字符串, 同时也是数组, 下标从 0 开始, 所以 i 初始值设置为 0 */ /* n 是记录 bb 数组中下一个新加入的下标保存 到的位置 */ /* 由于刚开始 bb 数组中没有任何保存进来的 下标,所以 n 初始值设置为 0 */ int i=0,n=0; char t= /* p 指针指向 str 字符串第一个字符, 为进行循 环作准备 */ char *p= /* while(*p)是 while(*p!= '\0')的简写方式 */ /* while(*p)表示 p 指针到达 str 字符串结尾处循 环就结束 */ while ( *p ) { /* 如果 p 指向的字符和 ch 参数的字符相 if(*p==t ) /* 在 bb 数组中加入该字符的下标 i */ /* 同时将记录 bb 数组最后位置的 n 加一,作为下一个下标的位置 */ bb[n++]=i; /* p 指针移动到 str 字符串的下一个字符位 置并指向它 */ p++; /* i 和 p 指针是同步的,记录 p 指针指向 字符在 str 数组中的下标*/ i++; /* 以上 while 循环结束之后,n 变量的值是 bb 数组中的元素个数 */ /* 而 n 变量记录的元素个数是在 str 字符串中 找到的和 ch 相同的字符个数 */ } main() { char str[N]; int i,j,n; /* clrscr 函数用于清除输出窗口中已经显示的 内容 */ /* clrscr 函数定义在 conio.h , 所以需要#include &conio.h& */ clrscr() ; /* 在输出窗口输出提示信息&******* Input the original string*******& */ printf(&******* string*******\n &); /* 使用 gets 函数接收键盘输入的字符串, 输入 的字符串存入 str 数组 */ /* gets 函数定义在 stdio.h 中, 所以需要#include &stdio.h& */ gets(str); printf(&******* The Original string *******\n&); /* 使用 puts 函数在输出窗口中显示参数 str 字 符串的内容 */ /* puts 函数定义在 stdio.h 中, 所以需要#include &stdio.h& */ puts(str); printf(&******* Input character *******\n&); scanf(&%c&,&ch); n=fun(str,ch); printf(& \nThe number of character is: %d\n&,n); printf(&******* *******\n&); /* 将 bb 数组中记录的在 str 字符串中找到的和 ch 字符相同的字符的下标 */ for(i=0;i&n;i++) printf(& %d &,bb[i]); } (19) 题目: 给定程序的功能是计算 score 中 m 个人的平均成 绩 aver,将低于 aver 的成绩放在 below 中,通过函 数名返回人数。 例如,当 score={10,20,30,40,50,60,70, 80,90},m=9 时,函数返回的人数应该是 4, below={10,20,30,40}。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在横线上填入所编写的若干表达式或语句。 #include &stdio.h& int fun(int score[], int m, int below[]) { int i, j = 0 ; float aver = 0.0 ; for(i = 0 ; i & i++) aver += score[i] ; aver /= (float) The suffix of character Input the original } 分析: 90} ; }for(i = 0 ; i & i++) if(score[i] & aver) below[j++] = ___1___ ; main() { int i, n, below[9] ; int score[9] = {10, 20, 30, 40, 50, 60, 70, 80, n = fun(score, 9, ___2___) ; printf( &\nBelow the average score are: & ) ; for (i = 0 ; i & i++) printf(&%d &, ___3___) ; printf(&\n&);于平均分 */ for(i = 0 ; i & i++) if(score[i] & aver) /* 将低于平均分的成绩放入 below 数 组,j 指示放入的位置 */ /* below[j++] = score[i];相当于以下两 句 */ /* below[j] = score[i]; */ /* j++; */ /* j++先使用 j 的当前值作为 j++表达 式的整体值,然后再将 j 加一 */ below[j++] = score[i] ; /* for 循环结束的时候,j 的值为 below 数组中 成员的个数 */ /* 也就是低于平均分的人数或者成绩个数 */ } main() { int i, n, below[9] ; /* score 数组存放 9 个人的成绩 */ int score[9] = {10, 20, 30, 40, 50, 60, 70, 80, 90} ; /* 调用 fun 函数进行题目要求的处理过程,返 回低于平均分的成绩个数 n */ n = fun(score, 9, below) ; /* 在 输 出 窗 口 输 出 提 示 信 息 &Below the average score are: & */ printf( &\nBelow the average score are: & ) ; /* 将 below 数组中保存的低于平均分的所有成 绩全部输出在输出窗口 */ for (i = 0 ; i & i++) printf(&%d &, below[i]) ; printf(&\n&); } (20)题目: 给定程序的功能是求出能整除 x 且不是偶数的各 整数, 并放在数组 pp 中, 这些除数的个数由 n 返回。 例如,若 x 的值为 30,则有 4 个数符合要求,它 们是 1,3,5,15。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在横线上填入所编写的若干表达式或语句。 #include &stdio.h& void fun(int x, int pp[], int *n) { int i, j = 0 ; for(i = 1 ; i &= i +=2 ) if((x % i) == 0) pp[j++] = ___1___ ; *n = ___2___ ; } main() { int x, aa[1000], n, printf( &\nPlease enter an integer number:\n& ) ; scanf(&%d&, &x) ; fun(x, ___3___ ) ; for( i = 0 ; i & i++ )题目要求在 fun 函数中计算 score 数组中 m 个人 的平均成绩 aver, 将低于 aver 的所有成绩放在 below 数组中,并将 below 数组中元素的个数作为 fun 函 数的返回值。 为了实现以上要求,可以有以下思路: (1) 首先必须知道 score 数组中 m 个人的平均成 绩 aver,然后才能判断 score 数组中哪些成绩是低 于平均分的。为了得到这个平均分,程序可以使用 循环遍历 score 数组中所有的成绩,把这些成绩进 行累加之后除以 m 即可得到成绩的平均分。 (2) 得到平均分之后, 程序可以再次使用循环遍 历 score 数组中每一个成员元素,主意检查这些成 员元素是否低于平均分。如果低于平均分,则将其 放入 below 数组。 (3)将低于平均分的成绩放入 below 数组的时 候,程序需要知道成绩放在 below 数组中哪一个位 置。 放入的位置可以由变量 j 控制。 的初始值为 0, j 因为在 C 语言中数组第一个位置是以 0 开始的。当 有低于平均分的成绩放入 below 数组的时候, 的当 j 前值就是该成绩在 below 数组的放入位置,然后 j 当前值加一,指示下一个低于平均分的成绩放入 below 数组的位置。 程序注解如下: #include &stdio.h& /* score 数组存放 m 个人的成绩 */ /* below 数组存放在 m 个人中低于平均分的成绩, 初始的时候没有成绩在其中 */ int fun(int score[], int m, int below[]) { int i, j = 0 ; /* aver 为 score 数组中所有成绩的平均分 */ /* aver 定义为 float 类型主要由于计算得到的平 均分可能带有小数部分 */ float aver = 0.0 ; /* 遍历 score 数组,将所有的成绩进行累积, 得到的和放入 aver 变量 */ for(i = 0 ; i & i++) aver += score[i] ; /* 将 aver 中保存的成绩总和除以人数得到平 均分 */ aver /= (float) /* 再次遍历 score 数组,检查数组成员是否低 printf(&%d &, aa[i]) ; printf(&\n&) ; } 分析: 题目要求在 fun 函数中求出能整除 x 且不是偶数 的各整数,并放在数组 pp 中,这些除数的个数由 n 返回。为了实现以上要求,题目中的程序使用了以 下实现思路: (1) 为了查找整除 x 且不是偶数的各整数, 程序 使用 for 循环将整数 x 除以 1 至 x 范围之间的所有 奇数。如果能够整除,则将该奇数放入 pp 数组中。 (2)将奇数放入 pp 数组的时候,程序需要知道 在 pp 数组中的放入位置。这个位置由 j 变量记录。 j 变量的初始值为 0,因为放入 pp 数组的第一个奇 数应该放在数组第一个位置,而 C 语言语法规定数 组的第一个位置是以 0 开始的。 (3)在 for 循环中将符合能被 x 整除的奇数放入 pp 数组之后,j 的值也应该加一,以指示下一个奇 数放入 pp 数组的位置。fun 函数中的 pp[j++] =可 以拆分为以下两句: pp[j] = j++; 这是由于 j++和++j 的表达式值不同。j++首先先 提取 j 的当前值作为 j++表达式的整体值, 也就是在 pp 数组中的存放位置,然后再将 j 加一。而++j 先 将 j 加一,然后将 j 的当前值作为++j 表达式的整体 值, 也就是在 pp 数组中的存放位置。 其中的差别考 生需要细细体会。 (4)for 循环结束之后, 将存放 pp 数组中的成员 个数的 j 变量的值返回。由于 fun 函数返回类型为 void,所以不能使用 return 语句将 j 直接返回。 也就 是说不能使用以下语句: 程序使用参数 n 来接收 j 的值。C 语言的参数传 递方式默认为传值方式,例如以下的 fun 函数中的 n 参数就是采用传值方式。 void fun(int x, int pp[], int n) { …… n=j; } main() { …… fun(x, aa, n ) ; …… } 上面的 n 参数虽然在 fun 函数最后执行语句&n = &被赋值了 j 的值,但是当退出 fun 函数回到 main 函数之后, main 函数中的 n 变量的值还是保留调用 fun 函数之前的值, 也就是说在 fun 函数中针对 n 参 数的修改是无效的。这就是传值方式的特点。造成 这种现象的原因是参数 n 是一个形式参数,它的值 虽然和 main 函数中的 n 一样, 但是它是复制了 main 函数中的 n 的值,然后在内存其它地方保存(C 语 言中任何一个变量声明之后都各自占用内存某一地 址) n 参数的作用范围或者称为生存范围只限于在 。 fun 函数内部。当退出 fun 函数之后,n 参数就消失 了, 它所占用的内存空间地址也被释放。 所以在 fun 函数对 n 参数所作的修改当然丢失了。为了能够使在 fun 函数中针对 n 参数的修改有效, fun 函数必须使用另外一种参数传递方式,即地址 传值方式。这种方式下,main 函数传递给 fun 函数 的是指向 n 变量的指针,即先使用&运算符取得 n 变量在内存中的存放地址,然后将这个地址或者称 为指针传入 fun 函数。 参数 n 指针是一个形式参数, 它和传值方式一样, 也是复制了 main 函数中的传入的 n 变量地址的值, 然后保存在内存自己占用的地址(C 语言中任何一 个变量声明之后都各自占用内存某一地址) n 参数 。 指针的作用范围或者称为生存范围和传值方式一 样,也只限于在 fun 函数内部。当退出 fun 函数之 后,n 参数指针也消失了,它所占用的内存空间地 址也被释放。但是它在 fun 函数中使用*n=j 修改 n 指针所指向的地址里面的内容为 j 的值, 这样的话, 即时 n 参数指针消失了,但是通过这个指针修改的 其它地址中的内容 (其实是 main 函数中的 n 变量占 用的地址里面存放的内容,也就是 n 变量的值)还 是被保留下来的,所以在 fun 函数对 n 参数指针所 作的修改当然有效了。 (5)第一处填空处应该填写存入 pp 数组中的能 被 x 整除且不是偶数的整数,所以应该填写 i。for 循环中 i+=2 的目的就是淘汰偶数,因为 i 是从 1 开 始的。 (6) 题目要求在 fun 函数中求出能整除 x 且不是 偶数的各整数, 并放在数组 pp 中, 这些除数的个数 由 n 返回。所以第二处天空应该填写记录数组 pp 中成员个数的 j 变量。 (7)根据 fun 函数头的声明和 fun 函数程序我们 可以观察发现,fun 函数第二个参数是存放能被 x 整除且不是偶数的整数的数组,刚传入 fun 函数的 时候它的成员个数应该为 0, 所以对应 main 函数中 的数组应该为 aa 数组。而 fun 第三个参数是一个指 针变量,作用为保存能被 x 整除且不是偶数的整数 的个数, 也就是 pp 数组中的成员个数。 所以第三个 参数应该填写&n。&&&在这里是取地址的运算符, &n 表示取 n 变量在内存占用的地址, 地址其实就是 指针类型。 程序注解如下: #include &stdio.h& void fun(int x, int pp[], int *n) { int i, j = 0 ; /* 检查能被 x 整除且不是偶数的各整数, 并放 在数组 pp 中 */ /* i 从 1 开始,每次加 2,确保排除偶数 */ for(i = 1 ; i &= i +=2 ) /* 判断 x 能够被 i 整除 */ if((x % i) == 0) /* 将符合条件的整数放入 pp 数组 */ pp[j++] = /* 修改 n 指针所指示的地址里面的值为 j 变量 的值 */ *n = } main() { int x, aa[1000], n, printf( &\nPlease enter an integer number:\n& ) ; } } }scanf(&%d&, &x) ; fun(x, aa, &n ) ; /* 输出所有能被 x 整除且不是偶数的整数 */ for( i = 0 ; i & i++ ) printf(&%d &, aa[i]) ; printf(&\n&) ;(21)题目: 给定程序中,函数 fun 的功能是:将 s 所指字符 串中的所有数字字符移到所有非数字字符之后,并 保持数字字符串和非数字字符串原有的先后次序。 例如,形参 s 所指的字符串为:def35adh3kjsdf7。 执行结果为:defadhkjsdf3537。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在 fun 函数的横线上填入所编写的若干表达式或 语句。 #include &stdio.h& void fun(char *s) { int i, j=0, k=0; char t1[80], t2[80]; for(i=0; s[i]!='\0'; i++) if(s[i]&='0' && s[i]&='9') { t2[j]=s[i]; ___1___; } else t1[k++]=s[i]; t2[j]=0; t1[k]=0; for(i=0; i&k; i++) ___2___; for(i=0; i&___3___; i++) s[k+i]=t2[i]; main() { char s[80]=&ba3a54j7sd567sdffs&; printf(&\nThe original string is : %s\n&,s); fun(s); printf(&\nThe result is : %s\n&,s); 分析: 题目要求将 s 所指字符串中的所有数字字符移到 所有非数字字符之后,并保持数字字符串和非数字 字符串原有的先后次序。例如,形参 s 所指的字符 串 为 : def35adh3kjsdf7 。 执 行 结 果 为 : defadhkjsdf3537。为了实现以上要求,题目中的程 序使用了一下思路: (1)定义两个数组 t1、t2,准备分别存放原字符 串 s 中的非数字字符、数字字符。 (2)逐一检查字符串 s 中每一个字符,如果是非 数字字符, 则将其放入 t1 数组中。 如果是数字字符, 则将其放入 t2 数组中。 (3) 以上过程结束之后, t1 数组中的字符 将 (即 非数字字符)和 t2 数组中的字符(即数字字符)按 照顺序覆盖原字符串 s。这样就达到了题目的要求。 在程序中,需要判断某一个字符是否是非数字字 符还 是数字字 符。判断 方法就是检查 该字符 的 ASCII 码是否大于&0&字符的 ASCII 码而小于&9&的 ASCII 码。 也就是说只要某字符的 ASCII 码值在&0& 字符和&9&字符两个 ASCII 码值之间, 该字符就是数 字字符。 ASCII 全 称 是 美 国 标 准 信 息 交 换 码 (American Standard Code for Information Interchange)。在这张 表中,小写字母&0&的 ASCII 码值为 48,小写字母 &1&的 ASCII 码值为 49,小写字母&2&的 ASCII 码值 为 50,后面的数字字符的 ASCII 码值依次类推,最 后的&9&的 ASCII 码值为 57。所有的数字字符在 ASCII 码表中是按顺序排列的,它们在 ASCII 表的 码值开始于 48,结束于 57。 而根据 C 语言的语法,判断两个字符之间的大小 实际上是比较两个字符在 ASCII 表中的码值大小。 例如&7&字符大于&6&字符,因为&7&的 ASCII 码值为 55,&6&的 ASCII 码值为 54,&7&的 ASCII 码值大于 &6&的 ASCII 码值。使用 C 语言描述就是'7'&'6'这个 表达式成立。 综上所述,判断某个字符是否为数字字符只要判 断该字符的 ASCII 码值是否在&0&和&9&之间即可。 如果在这范围之内,该字符就是数字字符,否则不 是。 程序注解如下: #include &stdio.h& void fun(char *s) { int i, j=0, k=0; char t1[80], t2[80]; /* 逐一检查 s 字符串中每一个字符 */ for(i=0; s[i]!='\0'; i++) /* 如果当前字符是数字字符的时候 */ if(s[i]&='0' && s[i]&='9') { /* 将数字字符放入 t2 数组 t2[j]=s[i]; /* j 变量记录数字字符放入 t2 数组的位 置 */ /* 所以 j 需要加一,指示下一个数字 字符存放的位置 */ j++; } else /* 如果是非数字字符,则将其放入 t1 数组 */ /* k 变量记录非数字字符放入 t1 数组 的位置*/ /* t1[k++]=s[i]; 相 当 于 以 下 两 句 : t1[k]=s[i]; k++; */ t1[k++]=s[i]; /* 设置 t1、t2 数组的结束标记,j 记录数字字符 的个数,k 记录非数字字符个数 */ t2[j]=0; t1[k]=0; /* 将 t1 数组中的非数字字符覆盖 s 数组内容 */ for(i=0; i&k; i++) s[i]=t1[i]; *//* 将 t2 数组中的数字字符紧接着非数字字符覆 盖 s 数组内容 */ for(i=0; i& i++) s[k+i]=t2[i]; } main() { /* s 数组中的字符串为要处理的字符串 char s[80]=&ba3a54j7sd567sdffs&; /* 输 出 提 示 信 息 : &The original string is : ba3a54j7sd567sdffs& */ printf(&\nThe original string is : %s\n&,s); /* 调用 fun 函数处理 s 字符串, 使之符合题目要 求 */ fun(s); /* 输出处理之后的 s 字符串 */ printf(&\nThe result is : %s\n&,s); } (22) 题目: 给定程序中,函数 fun 的功能是:在形参 s 所指 字符串中的每个数字字符之后插入一个*号。 例如,形参 s 所指的字符串为:def35adh3kjsdf7。 执行结果为:def3*5adh3*kjsdf7*。 注意:部分源程序如 blank.c 给出。 请勿改动主函数 main 和其他函数中的任何内容, 仅在 fun 函数的横线上填入所编写的若干表达式或 语句。 #include &stdio.h& */都往后移动一个位置。 (3)在腾出的位置放入*号。 在程序中,需要判断某一个字符是否是数字字符。 判断方法就是检查该字符的 ASCII 码是否大于&0& 字符的 ASCII 码而小于&9&的 ASCII 码。 也就是说只 要某字符的 ASCII 码值在&0&字符和&9&字符两个 ASCII 码值之间,该字符就是数字字符。 ASCII 全 称 是 美 国 标 准 信 息 交 换 码 (American Standard Code for Information Interchange)。在这张 表中,小写字母&0&的 ASCII 码值为 48,小写字母 &1&的 ASCII 码值为 49,小写字母&2&的 ASCII 码值 为 50,后面的数字字符的 ASCII 码值依次类推,最 后的&9&的 ASCII 码值为 57。所有的数字字符在 ASCII 码表中是按顺序排列的,它们在 ASCII 表的 码值开始于 48,结束于 57。 而根据 C 语言的语法,判断两个字符之间的大小 实际上是比较两个字符在 ASCII 表中的码值大小。 例如&7&字符大于&6&字符,因为&7&的 ASCII 码值为 55,&6&的 ASCII 码值为 54,&7&的 ASCII 码值大于 &6&的 ASCII 码值。使用 C 语言描述就是'7'&'6'这个 表达式成立。 综上所述,判断某个字符是否为数字字符只要判 断该字符的 ASCII 码值是否在&0&和&9&之间即可。 如果在这范围之内,该字符就是数字字符,否则不 是。 程序注解如下: #include &stdio.h& void fun(char *s)void fun(char *s) { int i, j, char t1[80], t2[80]; for(i=0; s[i]!='\0'; i++) if(s[i]&='0' ___1___ s[i]&='9') { n=0; while(s[i+1+n]!= ___2___) n++; for(j=i+n+1; j&i; j--) s[j+1]= ___3___; s[j+1]='*'; i=i+1; } } main() { char s[80]=&ba3a54cd23a&; printf(&\nThe original string is : %s\n&,s); fun(s); printf(&\nThe result is : %s\n&,s);} 分析: 题目要求在 fun 函数的形参 s 所指字符串中的每 个数字字符之后插入一个*号。为了实现以上要求, 题目的程序使用}

我要回帖

更多关于 if函数的使用方法嵌套 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信