C | C控制语句:循环

目录

一、再探while循环

1.1 程序注释

1.2 C风格读取循环

二、while语句

2.1 终止while循环

2.2 何时终止循环

2.3 while:入口条件循环

2.4 语法要点

三、用关系运算符和表达式比较大小

3.1 什么是真

3.2 其他真值

3.3 真值的问题

 3.4 新的_Bool类型

3.5 优先级和关系运算符

 四、不确定循环和计数循环

五、for循环

5.1 利用for的灵活性

1、可以使用递减运算符来递减计数器

2、可以让计数器递增2、10等

3、可以用字符代替数字计数

4、除了测试迭代次数外,还可以测试其他条件。

5、可以让递增的量几何增长,而不是算术增长。

6、第3个表达式可以使用任意合法的表达式。

7、可以省略一个或多个表达式(但是不能省略分号),只要在循环中包含能结束循环的语句即可。

8、第1个表达式不一定是给变量赋初值,也可以使用printf()。在执行循环的其他部分之前,只对第1个表达式求值一次或执行一次。

9、循环体中的行为可以改变循环头中的表达式。

六、其他赋值运算符:+=、-=、*=、/=、%=

七、逗号运算符

八、出口条件循环:do while

九、如何选择循环

十、嵌套循环

10.1 程序分析

10.2 嵌套变式

十一、数组简介

11.1 在for循环中使用数组

十二、使用函数返回值的循环示例

12.1 程序分析

12.2 使用带返回值的函数


一门语言应该提供以下3种形式的程序流

  • 执行语句序列;
  • 如果满足某些条件就重复执行语句序列(循环)
  • 通过测试选择执行哪一个语句序列(分支)。

一、再探while循环

示例程序:

#include <stdio.h>
int main(void)
{
	long num;
	long sum = 0L; /* 把sum初始化为0 */
	int status;
	printf("Please enter an integer to be summed ");
	printf("(q to quit): ");
	status = scanf("%ld", &num);
	while (status == 1) /* == 的意思是“等于” */
	{
		sum = sum + num;
		printf("Please enter next integer (q to quit): ");
		status = scanf("%ld", &num);
	}
	printf("Those integers sum to %ld.\n", sum); 

	getchar();
	getchar();
	getchar();
	return 0;
}

运行结果:

Please enter an integer to be summed (q to quit): 210
Please enter next integer (q to quit): 80
Please enter next integer (q to quit): 5
Please enter next integer (q to quit): q
Those integers sum to 295.

该程序使用long类型以储存更大的整数。尽管C编译器会把0自动转换为合适的类型,但是为了保持程序的一致性,我们把sum初始化为0L(long类型的0),而不是0(int类型的0)。

1.1 程序注释

scanf()返回成功读取项的数量。如果 scanf()在转换值之前出了问题(例如,检测到文件结尾或遇
到硬件问题),会返回一个特殊值EOF(其值通常被定义为-1)。这个值也会引起循环终止。

while循环的标准格式伪代码:

获得第1个用于测试的值
当测试为真时
        处理值
        获取下一个值

1.2 C风格读取循环

下面代码:

status = scanf("%ld", &num);
while (status == 1)
{
/* 循环行为 */
status = scanf("%ld", &num);
}

 可以被替换为:

while (scanf("%ld", &num) == 1)
{
/*循环行为*/
}

所以,while循环的精简版本伪代码为:

当获取值和判断值都成功
处理该值

二、while语句

while循环的通用形式如下:
while ( expression )
statement

statement部分可以是以分号结尾的简单语句,也可以是用花括号括起来的复合语句

expression是值之间的比较,可以使用任何表达式

每次循环都被称为一次迭代(iteration)

2.1 终止while循环

在构建while循环时,必须让测试表达式的值有变化,表达式最终要为假

例如:

index = 1;
while (--index < 5)
printf("Good morning!\n");

在index减少到其类型到可容纳的最小负值并变成最大正值时会终止循环。

2.2 何时终止循环

#include <stdio.h>
int main(void)
{
	int n = 5;
	while (n < 7) // 第7行
	{
		printf("n = %d\n", n);
		n++; // 第10行
		printf("Now n = %d\n", n); // 第11行
	}
	printf("The loop has finished.\n");
	getchar();
	return 0;
}

运行结果:

n = 5
Now n = 6
n = 6
Now n = 7
The loop has finished.

2.3 while:入口条件循环

while循环是使用入口条件有条件循环。所谓“有条件”指的是语句部分的执行取决于测试表达式描述的条件,如(index < 5)。

2.4 语法要点

无限循环(infinite loop) 的例子:

/* while1.c -- 注意花括号的使用 */
/* 糟糕的代码创建了一个无限循环 */
#include <stdio.h>
int main(void)
{
int n = 0;
while (n < 3)
printf("n is %d\n", n);
n++;
printf("That's all this program does\n");
return 0;
}

运行结果:

n is 0
n is 0
n is 0
n is 0
n is 0
...

关于放置分号的位置。

#include <stdio.h>
int main(void)
{
	int n = 0;
	while (n++ < 3); /* 第7行,注意此处的分号 */
	printf("n is %d\n", n); /* 第8行 */
	printf("That's all this program does.\n");
	getchar();
	return 0;
}

运行结果:

n is 4
That's all this program does.

测试条件后面的单独分号是空语句(null statement)

有的情况是故意使用空语句,例如:

while (scanf("%d", &num) == 1)
; /* 跳过整数输入 */

 这种情况更好的方法是使用continue语句

三、用关系运算符和表达式比较大小

while循环经常依赖测试表达式作比较,这样的表达式被称为关系表达式(relational expression),出现在关系表达式中间的运算符叫做关系运算符(relational operator)

  •  关系表达式可用于比较字符,但是,不能用关系运算符比较字符串
  • 关系运算符也可用来比较浮点数,但是要注意:比较浮点数时,尽量只使用<和>。因为浮点数的舍入误差会导致在逻辑上应该相等的两数却不相等
  • 使用fabs()函数(声明在math.h头文件中)可以方便地比较浮点数,该函数返回一个浮点值的绝对值(即,没有代数符号的值)。
#include <math.h>
#include <stdio.h>
int main(void)
{
	const double ANSWER = 3.14159;
	double response;
	printf("What is the value of pi?\n");
	scanf("%lf", &response);
	while (fabs(response - ANSWER) > 0.0001)
	{
		printf("Try again!\n");
		scanf("%lf", &response);
	}
	printf("Close enough!\n");
	getchar();
	getchar();
	return 0;
}

运行结果:

What is the value of pi?
3.141
Try again!
3.1416
Close enough!

3.1 什么是真

表达式一定有一个值,关系表达式也不例外。

#include <stdio.h>
int main(void)
{
	int true_val, false_val;
	true_val = (10 > 2); // 关系为真的值
	false_val = (10 == 2); // 关系为假的值
	printf("true = %d; false = %d \n", true_val, false_val);
	getchar();
	return 0;
}

运行结果:

true = 1; false = 0

对C而言,表达式为真的值是1,表达式为假的值是0

3.2 其他真值

#include <stdio.h>
int main(void)
{
	int n = 3;
	while (n)
		printf("%2d is true\n", n--);
	printf("%2d is false\n", n);
	n = -3;
	while (n)
		printf("%2d is true\n", n++);
	printf("%2d is false\n", n);
	getchar();
	return 0;
}

运行结果:

 3 is true
 2 is true
 1 is true
 0 is false
-3 is true
-2 is true
-1 is true
 0 is false

一般而言,所有的非零值都视为真,只有0被视为假。

许多C程序员都会很好地利用测试条件的这一特性。例如,用while (goats)替换while (goats !=0),

3.3 真值的问题

#include <stdio.h>
int main(void)
{
	long num;
	long sum = 0L;
	int status;

	printf("Please enter an integer to be summed ");
	printf("(q to quit): ");
	status = scanf("%ld", &num);
	while (status = 1)
	{
		sum = sum + num;
		printf("Please enter next integer (q to quit): ");
		status = scanf("%ld", &num);
	}
	printf("Those integers sum to %ld.\n", sum);
	getchar();
	getchar();
	return 0;
}

运行结果:

  •  整个赋值表达式的值就是赋值运算符左侧的值。
  • 如果scanf()读取指定形式的输入失败,就把无法读取的输入留在输入队列中,供下次读取。
  • 比较是否相等的表达式时,都习惯把常量放在左侧。

 3.4 新的_Bool类型

在编程中,表示真或假的变量被称为布尔变量(Boolean variable)

Bool类型的变量只能储存1(真)或0(假)。如果把其他非零数值赋给_Bool类型的变量,该变量会被设置为1。这反映了C把所有的非零值都视为真。

#include <stdio.h>
int main(void)
{
	long num;
	long sum = 0L;
	_Bool input_is_good;
	printf("Please enter an integer to be summed ");
	printf("(q to quit): ");
	input_is_good = (scanf("%ld", &num) == 1);
	while (input_is_good)
	{
		sum = sum + num;
		printf("Please enter next integer (q to quit): ");
		input_is_good = (scanf("%ld", &num) == 1);
	}
	printf("Those integers sum to %ld.\n", sum);
	getchar();
	getchar();
	getchar();
	return 0;
}

运行结果:

Please enter an integer to be summed (q to quit): 5
Please enter next integer (q to quit): 6
Please enter next integer (q to quit): 4
Please enter next integer (q to quit): 2
Please enter next integer (q to quit): 1
Please enter next integer (q to quit): 1
Please enter next integer (q to quit): 1
Please enter next integer (q to quit): q
Those integers sum to 20.

  • input_is_good = (scanf("%ld", &num) == 1);圆括号提高代码可读性。
  • C99提供了stdbool.h头文件,该头文件让bool成为_Bool的别名,而且还把true和false分别定义为1和0的符号常量。

3.5 优先级和关系运算符

关系运算符的优先级比算术运算符(包括+和-)低,比赋值运算符高。

关系运算符之间有两种不同的优先级。
高优先级组: <  <=  >  >=
低优先级组: ==   !=

关系运算符的结合律是从左往右。

 四、不确定循环和计数循环

一些while循环是不确定循环(indefinite loop)。所谓不确定循环,指在测试表达式为假之前,预先不知道要执行多少次循环。还有一类是计数循环(counting loop)。这类循环在执行循环之前就知道要重复执行多少次。

// sweetie1.c -- 一个计数循环
#include <stdio.h>int main(void)
{
const int NUMBER = 5;
int count = 1; // 初始化
while (count <= NUMBER) // 测试
{
printf("Be my Valentine!\n"); // 行为
count++; // 更新计数
}
return 0;
}

运行结果:

Be my Valentine!
Be my Valentine!
Be my Valentine!
Be my Valentine!
Be my Valentine!

在创建一个重复执行固定次数的循环中涉及了3个行为:
1.必须初始化计数器;
2.计数器与有限的值作比较;
3.每次循环时递增计数器。

相比于使用count++ <= NUMBER的形式,上述程序不容易漏掉更新,单容易忽略初始化。

五、for循环

#include <stdio.h>
int main(void)
{
	const int NUMBER = 5;
	int count;
	for (count = 1; count <= NUMBER; count++)
		printf("Be my Valentine!\n");
	getchar();
	return 0;
}

运行结果:

Be my Valentine!
Be my Valentine!
Be my Valentine!
Be my Valentine!
Be my Valentine!

for循环把3个行为(初始化、测试和更新)组合在一处。

关键字for后面的圆括号中有3个表达式,分别用两个分号隔开。

  • 第1个表达式是初始化,只会在for循环开始时执行一次。
  • 第 2 个表达式是测试条件,在执行循环之前对表达式求值。如果表达式为假,循环结束。
  • 第3个表达式执行更新,在每次循环结束时求值。
     

 for圆括号中的表达式也叫做控制表达式,它们都是完整表达式,所以每个表达式的副作用(如,递增变量)都发生在对下一个表达式求值之前

#include <stdio.h>
int main(void)
{
	int num;
	printf(" n n cubed\n");
	for (num = 1; num <= 6; num++)
		printf("%-5d %-5d\n", num, num*num*num);
	getchar();
	return 0;
}

运行结果:

 n n cubed
1     1
2     8
3     27
4     64
5     125
6     216

5.1 利用for的灵活性

前面程序的for循环:第1个表达式给计数器赋初值,第2个表达式表示计数器的范
围,第3个表达式递增计数器。

for循环还有其他9种用法:

1、可以使用递减运算符来递减计数器

#include <stdio.h>
int main(void)
{
	int secs;
	for (secs = 5; secs > 0; secs--)
		printf("%d seconds!\n", secs);
	printf("We have ignition!\n");
	getchar();
	return 0;
}

运行结果:

5 seconds!
4 seconds!
3 seconds!
2 seconds!
1 seconds!
We have ignition!

2、可以让计数器递增2、10等

#include <stdio.h>
int main(void)
{
	int n; // 从2开始,每次递增13
	for (n = 2; n < 60; n = n + 13)
		printf("%d \n", n);
	getchar();
	return 0;
}

运行结果:

2
15
28
41
54

3、可以用字符代替数字计数

#include <stdio.h>
int main(void)
{
	char ch; 
	for (ch = 'a'; ch <= 'z'; ch++)
		printf("The ASCII value for %c is %d.\n", ch, ch);
	getchar();
	return 0;
}

运行结果:

The ASCII value for a is 97.
The ASCII value for b is 98.
The ASCII value for c is 99.
...
The ASCII value for y is 121.
The ASCII value for z is 122.

4、除了测试迭代次数外,还可以测试其他条件。

#include <stdio.h>
int main(void)
{
	int num;
	printf(" n n cubed\n");
	for (num = 1; num*num*num <= 216; num++)
		printf("%-5d %-5d\n", num, num*num*num);
	getchar();
	return 0;
}

运行结果:

 n n cubed
1     1
2     8
3     27
4     64
5     125
6     216

5、可以让递增的量几何增长,而不是算术增长。

#include <stdio.h>
int main(void)
{
	double debt;
	for (debt = 100.0; debt < 150.0; debt = debt * 1.1)
		printf("Your debt is now $%.2f.\n", debt);
	getchar();
	return 0;
}

运行结果:

Your debt is now $100.00.
Your debt is now $110.00.
Your debt is now $121.00.
Your debt is now $133.10.
Your debt is now $146.41.

6、第3个表达式可以使用任意合法的表达式。

#include <stdio.h>
int main(void)
{
	int x;
	int y = 55;
	for (x = 1; y <= 75; y = (++x * 5) + 50)
		printf("%10d %10d\n", x, y);
	getchar();
	return 0;
}

运行结果:

         1         55
         2         60
         3         65
         4         70
         5         75

for循环中的3个表达式可以是不同的变量。

虽然该例可以正常运行,但是编程风格不太好。如果不在更新部分加入代数计算,程序会更加清楚。

for (x = 1; y <= 75; ++x){

                y = (x * 5) + 50;
                printf("%10d %10d\n", x, y);}

7、可以省略一个或多个表达式(但是不能省略分号),只要在循环中包含能结束循环的语句即可。

#include <stdio.h>
int main(void)
{
	int ans, n;
	ans = 2;
	for (n = 3; ans <= 25;)
		ans = ans * n;
	printf("n = %d; ans = %d.\n", n, ans);
	getchar();
	return 0;
}

运行结果:

n = 3; ans = 54.

省略第2个表达式被视为真。

8、第1个表达式不一定是给变量赋初值,也可以使用printf()。在执行循环的其他部分之前,只对第1个表达式求值一次或执行一次。

#include <stdio.h>
int main(void)
{
	int num = 0;
	for (printf("Keep entering numbers!\n"); num != 6;)
		scanf("%d", &num);
	printf("That's the one I want!\n");
	getchar();
	getchar();
	return 0;
}

运行结果:

Keep entering numbers!
1
2
6
That's the one I want!

9、循环体中的行为可以改变循环头中的表达式。

for (n = 1; n < 10000; n = n + delta)

 循环中的if语句可以改变delta的大小。

总结:

for语句是一种入口条件循环

形式:
for ( initialize; test; update )
statement

在test为假或0之前,重复执行statement部分

六、其他赋值运算符:+=、-=、*=、/=、%=

scores += 20
dimes -= 2
bunnies *= 2
time /= 2.73
reduce %= 3




scores = scores + 20
dimes = dimes - 2
bunnies = bunnies * 2
time = time / 2.73
reduce = reduce % 3
相同

x *= 3 * y + 12 与 x = x * (3 * y + 12) 相同

以上提到的赋值运算符与=的优先级相同,即比+或*优先级低

优点:

  • 让代码更紧凑;
  • 与一般形式相比,组合形式的赋值运算符生成的机器代码更高效。

七、逗号运算符

逗号运算符扩展了for循环的灵活性,以便在循环头中包含更多的表达式。

#include <stdio.h>
int main(void) {
	const int FIRST_OZ = 46; // 2013邮资
	const int NEXT_OZ = 20; // 2013邮资
	int ounces, cost;
	printf(" ounces cost\n");
	for (ounces = 1, cost = FIRST_OZ; ounces <= 16;
	ounces++, cost += NEXT_OZ)
		printf("%5d $%4.2f\n", ounces, cost / 100.0);
	getchar();
	return 0;
}

运行结果:

 ounces cost
    1 $0.46
    2 $0.66
    3 $0.86
    4 $1.06
    5 $1.26
    6 $1.46
    7 $1.66
    8 $1.86
    9 $2.06
   10 $2.26
   11 $2.46
   12 $2.66
   13 $2.86
   14 $3.06
   15 $3.26
   16 $3.46

逗号运算符并不局限于在for循环中使用,但是这是它最常用的地方。

性质:

  • 它保证了被它分隔的表达式从左往右求值(换言之,逗号是一个序列点,所以逗号左侧项的所有副作用都在程序执行逗号右侧项之前发生)。
  • 整个逗号表达式的值是右侧项的值
  • 逗号也可用作分隔符。在下面语句中的逗号都是分隔符,不是逗号运算符:

char ch, date;

printf("%d %d\n", chimps, chumps);

  • 逗号运算符的优先级要低于赋值运算符,是优先级最低的运算符

Zeno遇到for循环

/* zeno.c -- 求序列的和 */
#include <stdio.h>
int main(void)
{
	int t_ct; // 项计数
	double time, power_of_2;
	int limit; 
	printf("Enter the number of terms you want: ");
	scanf("%d", &limit);
	for (time = 0, power_of_2 = 1, t_ct = 1; t_ct<= limit;
		t_ct++, power_of_2 *= 2.0)
	{
		time += 1.0 / power_of_2;
		printf("time = %f when terms = %d.\n", time, t_ct);
	}
	getchar();
	getchar();
	return 0;
}

运行结果:

Enter the number of terms you want: 25
time = 1.000000 when terms = 1.
time = 1.500000 when terms = 2.
time = 1.750000 when terms = 3.
time = 1.875000 when terms = 4.
time = 1.937500 when terms = 5.
time = 1.968750 when terms = 6.
time = 1.984375 when terms = 7.
time = 1.992188 when terms = 8.
time = 1.996094 when terms = 9.
time = 1.998047 when terms = 10.
time = 1.999023 when terms = 11.
time = 1.999512 when terms = 12.
time = 1.999756 when terms = 13.
time = 1.999878 when terms = 14.
time = 1.999939 when terms = 15.
time = 1.999969 when terms = 16.
time = 1.999985 when terms = 17.
time = 1.999992 when terms = 18.
time = 1.999996 when terms = 19.
time = 1.999998 when terms = 20.
time = 1.999999 when terms = 21.
time = 2.000000 when terms = 22.
time = 2.000000 when terms = 23.
time = 2.000000 when terms = 24.
time = 2.000000 when terms = 25.

启示:在进行复杂的计算之前,先看看数学上是否有简单的方法可用

八、出口条件循环:do while

while循环和for循环都是入口条件循环,即在循环的每次迭代之前检查测试条件,所以有可能根本不执行循环体中的内容。

C语言还有出口条件循环(exit-condition loop),即在循环的每次迭代之后检查测试条件,这保证了至少执行循环体中的内容一次。这种循环被称为 do while循环。

#include <stdio.h>
int main(void)
{
	const int secret_code = 13;
	int code_entered;
	do
	{
		printf("To enter the triskaidekaphobia therapy club,\n");
		printf("please enter the secret code number: ");
		scanf("%d", &code_entered);
	} while (code_entered != secret_code);
	printf("Congratulations! You are cured!\n");
	getchar();
	getchar();
	getchar();
	return 0;
}

运行结果:

To enter the triskaidekaphobia therapy club,
please enter the secret code number: 5
To enter the triskaidekaphobia therapy club,
please enter the secret code number: 13
Congratulations! You are cured!

使用while循环也能写出等价的程序,但是长一些。

#include <stdio.h>
int main(void)
{
	const int secret_code = 13;
	int code_entered;
	printf("To enter the triskaidekaphobia therapy club,\n");
	printf("please enter the secret code number: ");
	scanf("%d", &code_entered);
	while (code_entered != secret_code)
	{
		printf("To enter the triskaidekaphobia therapy club,\n");
		printf("please enter the secret code number: ");
		scanf("%d", &code_entered);
	}
	printf("Congratulations! You are cured!\n");
	getchar();
	getchar();
	return 0;
}

do while循环的通用形式:
do
statement
while ( expression );

do while循环以分号结尾

九、如何选择循环

选择入口循环还是出口循环。

  • 当循环涉及初始化和更新变量时,用for循环比较合适。
  • 对于涉及索引计数的循环,用for循环更适合。

十、嵌套循环

嵌套循环(nested loop)指在一个循环内包含另一个循环。嵌套循环常用于按行和列显示数据。

#include <stdio.h>
#define ROWS 6
#define CHARS 10
int main(void)
{
	int row;
	char ch;

	for (row = 0; row < ROWS; row++) /* 第10行 */
	{
		for (ch = 'A'; ch < ('A' + CHARS); ch++) /* 第12行 */
			printf("%c", ch);
		printf("\n");
	}
	getchar();
	return 0;
}

运行结果:

ABCDEFGHIJ
ABCDEFGHIJ
ABCDEFGHIJ
ABCDEFGHIJ
ABCDEFGHIJ
ABCDEFGHIJ

10.1 程序分析

外层循环(outer loop)
内层循环(inner loop)

嵌套循环中的内层循环在每次外层循环迭代时都执行完所有的循环。

10.2 嵌套变式

当内层循环开始打印的字符取决于外层循环的迭代次数。

#include <stdio.h>
int main(void)
{
	const int ROWS = 6;
	const int CHARS = 6; 
	int row;
	char ch;
	for (row = 0; row < ROWS; row++)
	{
		for (ch = ('A' + row); ch < ('A' + CHARS);ch++)
			printf("%c", ch);
		printf("\n");
	}
	getchar();
	return 0;
}

运行结果:

ABCDEF
BCDEF
CDEF
DEF
EF
F

十一、数组简介

数组(array)按顺序储存的一系列类型相同的值

  • C 编译器不会检查数组的下标是否正确。当运行程序时,这会导致数据被放置在已被其他数据占用的地方,可能会破坏程序的结果甚至导致程序异常中断。
  • 数组的类型可以是任意数据类型
  • 如果char类型的数组末尾包含一个表示字符串末尾的空字符\0,则该数组中的内容就构成了一个字符串

用 于 识 别 数 组 元 素 的 数 字 被 称 为 下 标 ( subscript ) 索 引(indice)偏移量(offset)。下标必须是整数,而且要从0开始计数。数组的元素被依次储存在内存中相邻的位置

11.1 在for循环中使用数组

用for循环来读取数据。

#include <stdio.h>
#define SIZE 10
#define PAR 72
int main(void)
{
	int index, score[SIZE];
	int sum = 0;
	float average;
	printf("Enter %d golf scores:\n", SIZE);
	for (index = 0; index < SIZE; index++)
		scanf("%d", &score[index]); // 读取10个分数
	printf("The scores read in are as follows:\n");
	for (index = 0; index < SIZE; index++)
		printf("%5d", score[index]); // 验证输入
	printf("\n");
	for (index = 0; index < SIZE; index++)
		sum += score[index]; // 求总分数
	average = (float)sum / SIZE; // 求平均分
	printf("Sum of scores = %d, average = %.2f\n",
		sum, average);
	printf("That's a handicap of %.0f.\n", average - PAR);
	getchar();
	getchar();
	return 0;
}

运行结果:

Enter 10 golf scores:
99 95 109 105 100
96 98 93 99 97 98
The scores read in are as follows:
   99   95  109  105  100   96   98   93   99   97
Sum of scores = 991, average = 99.10
That's a handicap of 27.

  • 用#define 指令创建的明示常量(SIZE)来指定数组的大小。
  • 下面的代码可以很方便地处理一个大小为SIZE的数组:

for (index = 0; index < SIZE; index++)

  • 程序能重复显示刚读入的数据。
  • 该程序使用了3个独立的for循环。

十二、使用函数返回值的循环示例

计算数的整数次幂(math.h库提供了一个更强大幂函数pow(),可以使用浮点指数)。
 

// power.c -- 计算数的整数幂
#include <stdio.h>
double power(double n, int p); // ANSI函数原型
int main(void)
{
	double x, xpow;
	int exp;
	printf("Enter a number and the positive integer power"); 
	printf(" to which\nthe number will be raised. Enter q");
	printf(" to quit.\n");
	while (scanf("%lf%d", &x, &exp) == 2)
	{
		xpow = power(x, exp); // 函数调用
		printf("%.3g to the power %d is %.5g\n", x, exp,
			xpow);
		printf("Enter next pair of numbers or q to quit.\n");
	}
	printf("Hope you enjoyed this power trip -- bye!\n");
	getchar();
	getchar();
	return 0;
}

double power(double n, int p) // 函数定义
{
	double pow = 1;
	int i;
	for (i = 1; i <= p; i++)
		pow *= n;
	return pow; // 返回pow的值
}

运行结果:

Enter a number and the positive integer power to which
the number will be raised. Enter q to quit.
12 2
12 to the power 2 is 144
Enter next pair of numbers or q to quit.
2.2 5
2.2 to the power 5 is 51.536
Enter next pair of numbers or q to quit.
q
Hope you enjoyed this power trip -- bye!

  • 函数可以返回一个变量的值,也可以返回表达式的值
  • 如果成功读取两个值,scanf()则返回2。

12.1 程序分析

该程序示例中的main()是一个驱动程序(driver),即被设计用来测试函数的小程序

12.2 使用带返回值的函数

问题:为什么在使用scanf()的返回值之前没有声明scanf()?
为什么在定义中说明了power()的返回类型为double,还要单独声明这个函数?

编译器在程序中首次遇到power()时,需要知道power()的返回类型。此时,编译器尚未执行到power()的定义,并不知道函数定义中的返回类型是double。因此,必须通过前置声明(forward declaration)预先说明函数的返回类型。前置声明告诉编译器,power()定义在别处,其返回类型为double如果把power()函数的定义置于main()的文件顶部,就可以省略前置声明,因为编译器在执行到main()之前已经知道power()的所有信息。通常把函数放在其他文件中,所以前置声明必
不可少。

stdio.h 头文件中包含了scanf()、printf()和其他I/O函数的原型。scanf()函数的原型表明,它返回的类型是int。

现代的编程习惯是把程序要素分为接口部分实现部分,例如函数原型和函数定义。接口部分描述了如何使用一个特性,也就是函数原型所做的;实现部分描述了具体的行为,这正是函数定义所做的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

HaGoq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值