函数基本结构
例1.打印(1)
#include<stdio.h>
void chline(char, int, int); //在声明函数时至少输入形式参数的型
int main(void)
{
int x, m, n;
scanf("%c %d %d", &x, &m, &n);
chline(x, m, n); //函数调用
return 0;
}
void chline(char a, int row, int col) //定义函数时要完整输入形参的型和名
{
int i, j;
for (i = 1; i <= row; i++)
{
for (j = 1; j <= col; j++)
{
printf("%c ", a);
}
printf("\n");
}
}
h 3 4
h h h h
h h h h
h h h h
例2.打印(2)
#include<stdio.h>
void repo(char);
int main(void)
{
char a;
while ((a = getchar()) != EOF)
{
repo(a);
}
return 0;
}
void repo(char a)
{
if (a >= 65 && a <= 90)
{
printf("%d ", a - 64);
}
else if (a >= 97 && a <= 122)
{
printf("%d ", a - 96);
}
else
{
printf("-1 ");
}
}
aaa bbb AAA BBB
1 1 1 -1 2 2 2 -1 1 1 1 -1 2 2 2 -1 ^Z
例3.四则运算
#include<stdio.h>
double harmonic_nean(double, double); //在声明函数时至少输入形式参数的型
int main(void)
{
double m, n;
scanf("%lf %lf",&m, &n);
printf("%lf\n", harmonic_nean(m, n)); //函数调用
return 0;
}
double harmonic_nean(double a, double b) //定义函数时要完整输入形参的型和名
{
return 1.0 / ((1.0 / a + 1.0 / b) / 2.0);
}
1 2
1.333333
测字符串长度
注意使用strlen()函数前先include<string.h>头文件
#include<stdio.h>
#include <string.h>
int main(void)
{
printf("The length of |aaaaaaa| is %d.", strlen("aaaaaaa"));
return 0;
}
The length of |aaaaaaa| is 7.
条件运算符 ? :
这是C中唯一的三元运算符
最简单的用法就是比大小
以下imin()和imax()函数示例
#include<stdio.h>
int imin(int a, int b);
int imax(int a, int b);
int main(void)
{
printf("%d is bigger.\n", imax(232, 3423));
printf("%d is smaller.\n", imin(232, 3423));
return 0;
}
int imin(int a, int b)
{
return (a < b) ? a : b;
}
int imax(int a, int b)
{
return (a > b) ? a : b;
}
3423 is bigger.
232 is smaller.
另外,将函数定义放在主程序前面也可,此时函数定义也是声明可以省略一些空间,不影响运行
#include<stdio.h>
int imin(int a, int b)
{
return (a < b) ? a : b;
}
int imax(int a, int b)
{
return (a > b) ? a : b;
}
int main(void)
{
printf("%d is bigger.\n", imax(232, 3423));
printf("%d is smaller.\n", imin(232, 3423));
return 0;
}
3423 is bigger.
232 is smaller.
指针与函数
指针"*"可看作寻址"&"的逆运算,如
a = &b; //把变量b的地址赋给变量a(b所在房间命名为a),注意地址是常量不可被赋值(即不可在左)
c = *a; //把地址a指向的变量值赋给c(在a房间内者命名为c)
此时毫无疑问
b == c;
以下程序中的函数(副程序)通过调整指针对主程序施加影响,回传值不要
此时函数可以不仅限单独作用或给主程序回传一个值,而可以实现更多功能
例1
#include<stdio.h>
void larger_of(double * a, double * b);
//double a表示双精度浮点型变量a
//double * a表示地址a指向一个双精度浮点型变量(a房间里有一个double型变量)
void interchange(double *, double *);
int main(void)
{
double m, n;
printf("Enter a pair of numbers (separating with a space): ");
scanf("%lf %lf", &m, &n);
interchange(&m, &n);
printf("Result of interchange: %.2f %.2f\n",m, n);
larger_of(&m, &n); //把地址(实参&m,&n)传给函数,此函数中是给形参a,b
printf("The bigger one: %.2f\n", m);
return 0;
}
void larger_of(double * a, double * b)
{
if (*a < *b) //如果a房间中的数小于b房间中的数
{
*a = *b; //让b房间的数覆盖原来a房间的数
}
else //否则
{
*b = *a; //让a房间的数覆盖原来b房间的数
}
}
void interchange(double * a, double * b)
{
double temp;
temp = *a; //把a房间的数先叫作temp
*a = *b; //让b房间的数覆盖a房间的数
*b = temp; //让原来a房间的数覆盖b房间的数
}
Enter a pair of numbers (separating with a space): 88.55 88.45
Result of interchange: 88.45 88.55 //此时看似交换了数,实际交换了数所在的房间
The bigger one: 88.55
例2
#include<stdio.h>
void sort_3(double * a, double * b, double * c);
void interchange(double * a, double * b);
int main(void)
{
double a, b, c;
printf("Enter 3 numbers (separating with spaces):\n");
while (scanf("%lf %lf %lf", &a, &b, &c) == 3)
{
sort_3(&a, &b, &c); //此处传入的是地址
printf("Sorting result:\n");
printf("%.0f %.0f %.0f\n\n", a, b, c);
printf("Enter 3 numbers (separating with spaces):\n");
}
return 0;
}
//以下交换方法仅对3数排序有效,更多数的排序参照冒泡(循环)和快排(递归)
void sort_3(double * a, double * b, double * c)
{
if (*a > *c)
interchange(a, c); //此处传入的也是地址
if (*b > *c)
interchange(b, c);
if (*a > *b)
interchange(a, b);
}
void interchange(double * a, double * b)
{
double temp;
temp = *a;
*a = *b;
*b = temp;
}
Enter 3 numbers (separating with spaces):
1 2 3
Sorting result:
1 2 3
Enter 3 numbers (separating with spaces):
1 3 2
Sorting result:
1 2 3
Enter 3 numbers (separating with spaces):
2 1 3
Sorting result:
1 2 3
Enter 3 numbers (separating with spaces):
2 3 1
Sorting result:
1 2 3
Enter 3 numbers (separating with spaces):
3 1 2
Sorting result:
1 2 3
Enter 3 numbers (separating with spaces):
3 2 1
Sorting result:
1 2 3
Enter 3 numbers (separating with spaces):
quit
循环与递归
整数指数幂
循环版
#include<stdio.h>
double power_z(double a, int b);
int main(void)
{
double a;
int b;
printf("%f\n", power_z(2, 1));
printf("%f\n", power_z(2, 5));
printf("%f\n", power_z(2, -2));
printf("%f\n", power_z(2, 0));
printf("%f\n", power_z(0, 44));
printf("%f\n", power_z(1.1, 44));
printf("%f\n", power_z(1.1, -44));
printf("%f\n", power_z(-2, 3));
printf("%f\n", power_z(-2, -3));
printf("%f\n", power_z(-1.1, -43));
printf("%f\n", power_z(-1.1, 0));
printf("%f\n", power_z(0, 0));
return 0;
}
double power_z(double a, int b)
{
if (b > 0)
{
int i;
if (a == 0)
{
return 0;
}
else
{
double e = 1;
for (i = 0; i < b; i++) //使用循环进行累乘
{
e *= a;
}
return e;
}
}
if (b == 0)
{
if (a != 0)
{
return 1;
}
else
{
printf("Result for 0 to the power of 0 is undefined.\n");
printf("It will be processed as 1.\n");
return 1;
}
}
if (b < 0)
{
int j, c;
c = -b;
if (a == 0)
{
return 0;
}
else
{
double f = 1;
for (j = 0; j < c; j++)
{
f *= a;
}
return 1 / f;
}
}
}
2.000000
32.000000
0.250000
1.000000
0.000000
66.264076
0.015091
-8.000000
-0.125000
-0.016600
1.000000
Result for 0 to the power of 0 is undefined.
It will be processed as 1.
1.000000
递归版
递归即是在某函数中调用其自身
为了防止无限递归的状况(像两面镜子互相照对方)
会在调用之前设定一个判断,限定递归次数
返回值的型 函数名A(参数的型 参数)
{
“递”部分的语句;
if(判断条件)
含有函数名A(参数)的语句;
“归”部分的语句;
...
return 返回值;
}
处理流程大致如下
递 | 归 |
---|---|
主程序调用第1级的函数 ↓ 执行第1级“递”部分的语句 ↓ 到条件语句时判断为真 ↓ 第1级的函数调用第2级的函数 ↓ ... ↓ 执行第n - 1级“递”部分的语句 ↓ 到条件语句时判断为真 ↓ 第n - 1级的函数调用第n级的函数 ↓ 执行第n级“递”部分的语句 ↓ 到条件语句时判断为假 | ↓ 执行第n级“归”部分的语句 ↓ 第n级返回值传回第n - 1级 ↓ 执行第n - 1级“归”部分的语句 ↓ ... ↓ 第2级返回值传回第1级 ↓ 执行第1级“归”部分的语句 ↓ 第1级的返回值传回主程序 |
递归与循环的相似之处可以看作是
第1~n轮循环中的每一次都执行完前半就进行下一轮
不满足判断条件后再按第n~1的顺序执行每一轮的后半
惟每调用一次函数就要多创建一次实参,过多次递归将会大量消耗内存
求整数指数幂的函数可改写如下:
#include<stdio.h>
double power_z(double a, int b);
int main(void)
{
double a;
int b;
printf("%f\n", power_z(2, 1));
printf("%f\n", power_z(2, 5));
printf("%f\n", power_z(2, -2));
printf("%f\n", power_z(2, 0));
printf("%f\n", power_z(0, 44));
printf("%f\n", power_z(1.1, 44));
printf("%f\n", power_z(1.1, -44));
printf("%f\n", power_z(-2, 3));
printf("%f\n", power_z(-2, -3));
printf("%f\n", power_z(-1.1, -43));
printf("%f\n", power_z(-1.1, 0));
printf("%f\n", power_z(0, 0));
return 0;
}
double power_z(double a, int b)
{
if (b > 0)
{
int i;
if (a == 0)
{
return 0;
}
else
{
double e = 1;
if (b > 0) //递归次数设限
{
e = a * power_z(a, b - 1); //调用自身,且使每次“递”都要接近次数限制(以渐化式形式)
}
return e;
}
}
if (b == 0)
{
if (a != 0)
{
return 1;
}
else
{
printf("Result for 0 to the power of 0 is undefined.\n");
printf("It will be processed as 1.\n");
return 1;
}
}
if (b < 0)
{
int j, c;
c = -b;
if (a == 0)
{
return 0;
}
else
{
double f = 1;
if (c > 0)
{
f = a * power_z(a, c - 1);
}
return 1 / f;
}
}
}
2.000000
32.000000
0.250000
1.000000
0.000000
66.264076
0.015091
-8.000000
-0.125000
-0.016600
1.000000
Result for 0 to the power of 0 is undefined.
It will be processed as 1.
1.000000
斐波那契数列
循环版
Fortran写法:
#include<stdio.h>
int fibonacci(int);
int main(void)
{
int i;
for (i = 1; i <= 20; i++)
printf("%d ", fibonacci(i));
return 0;
}
int fibonacci(int aim)
{
int a[10000], k;
a[0] = 0;
a[1] = 1;
for(k = 2; k < aim + 1; k++)
a[k] = a[k - 1] + a[k - 2];
return a[aim];
}
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
递归版
#include<stdio.h>
int fibonacci(int);
int main(void)
{
int i;
for (i = 1; i <= 20; i++)
printf("%d ", fibonacci(i));
return 0;
}
int fibonacci(int aim)
{
int a;
if (aim >= 3)
a = fibonacci(aim - 1) + fibonacci(aim - 2);
else if (aim == 1 || aim == 2)
a = 1;
return a;
}
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765
10进制→2或8进制
递归在“归”的部分是反着来的特点,使之适合于这种结果取反的问题
#include<stdio.h>
#include<ctype.h>
int to_base_n(int, int);
int main(void)
{
double b;
char ch;
b:
printf("Please enter a decimal number greater than 0 (decimal part will be cut automatically): ");
while(scanf("%lf", &b) != 1 || b <= 0)
{
printf("Please enter a decimal number greater than 0 (decimal part will be cut automatically): ");
while (getchar() != '\n')
{
continue;
}
}
a:
printf("Please choose a positional numeral system:\n");
printf("------------------------------------------\n");
printf(" a) binary b) octal\n");
printf("------------------------------------------\n");
fflush(stdin);
ch = getchar();
switch (ch)
{
case 'a':
printf("Result:");
to_base_n((int)b, 2);
printf("\n");
fflush(stdin);
break;
case 'b':
printf("Result:");
to_base_n((int)b, 8);
printf("\n");
fflush(stdin);
break;
default:
goto a;
}
c:
printf("Enter next number? (y/n)\n");
switch (getchar())
{
case 'y':
goto b;
case 'n':
break;
default:
printf("y or n, please.\n");
fflush(stdin);
goto c;
}
printf("Bye.\n");
return 0;
}
int to_base_n(int i, int n)
{
if (i >= n)
{
printf("%d", i - to_base_n(i / n, n) *n);
//余数 = 本次被除数 - 下次被除数(即本次的商) * 除数
}
else if (i >= 0 && i < n)
//被除数比除数小时,不再求余,而把被除数直接摆在开头
{
printf("%d", i);
}
return i;
}
Please enter a decimal number greater than 0 (decimal part will be cut automatically): q
Please enter a decimal number greater than 0 (decimal part will be cut automatically): .
Please enter a decimal number greater than 0 (decimal part will be cut automatically): -7
Please enter a decimal number greater than 0 (decimal part will be cut automatically): -1.1
Please enter a decimal number greater than 0 (decimal part will be cut automatically): 2.2
Please choose a positional numeral system:
------------------------------------------
a) binary b) octal
------------------------------------------
b
Result:2
Enter next number? (y/n)
y
Please enter a decimal number greater than 0 (decimal part will be cut automatically): 42
Please choose a positional numeral system:
------------------------------------------
a) binary b) octal
------------------------------------------
a
Result:101010
Enter next number? (y/n)
b
y or n, please.
Enter next number? (y/n)
y
Please enter a decimal number greater than 0 (decimal part will be cut automatically): 42
Please choose a positional numeral system:
------------------------------------------
a) binary b) octal
------------------------------------------
b
Result:52
Enter next number? (y/n)
n
Bye.