函数一
《function》
fun1.c
函数的说明及调用
函数名称、参数、返回值
求X^n的函数 ( x是实数 ,n为正整数 )
#include
double x = 2; // 定义全局变量 两个函数都可以使用 那么在main中引用power函数可以不用写参数
int n = 3; // 可直接写 ret = puwer();
// 定义全局变量不好的地方在于,任何函数都可以调用,参数值容易被修改,不建议使用全局变量
double power(double, int); //函数在主函数的下面,要在这引用
int main()
{
double x = 2, ret; // x 、n是局部变量 只能在 main 中使用
int n = 3; // 引用函数时注意变量的数据类型和函数需要的参数数据类型定义应相同
ret = power(x, n); //函数的调用
printf("%lf %d = %lf\n", x, n, ret);
return 0;
}
double power(double x, int n) // 函数的说明
{
double r = 1;
int i;
for (i = 1; i <= n; i++)
r *= x;
return r; //标注了函数的数据类型,就说明函数有返回值,就要有return
}
fun2.c
全局变量
#include
double x = 2;
int n = 3;
double power();
int main()
{
// double x = 2;
// int n = 3;
double ret;
ret = power();
printf("%lf %d = %lf\n", x, n, ret);
return 0;
}
double power()
{
double r = 1;
int i;
for (i = 1; i <= n; i++)
r *= x;
return r;
}
fun3.c
复制传递方式
#include
double power(double, int); // 1
int main()
{
double x = 2; // 2
int n = 3;
double ret;
printf("&x=%p &n=%p\n", &x, &n); //实参和形参有各自不同的存储空间
ret = power(x, n); // 3 如果改变函数参数的话,三个地方的参数都要同时改变
printf("%lf %d = %lf\n", x, n, ret);
return 0;
}
double power(double a, int b) //实参和形参的关系就是这样一个赋值的过程 double a = x; int b = n;
{ // 形参是新开辟的存储空间
double r = 1;
int i;
printf("&a=%p &b=%p\n", &a, &b);
for (i = 1; i <= b; i++)
r *= a;
return r;
}
fun4.c
函数实现两个数据的交换
#include
void swap(int x, int y);
int main()
{
int a = 10;
int b = 20;
printf("before:%d %d\n", a, b);
swap(a, b);
printf("after:%d %d\n", a, b);
return 0;
}
//int x = a; int y = b;
void swap(int x, int y) //形参的值改变,不会影响到实参
{
int t;
t = x;
x = y;
y = t;
}
fun5.c
函数实现两个数据的交换 指针实现 (重点)
即地址传递方式 被调用函数中对形参的操作,将直接改变实参的值(被调用函数对指针的目标操作,相当于对实参本身的操作)
#include
void swap(int * x, int * y);
int main()
{
int a = 10;
int b = 20;
printf("before:%d %d\n", a, b);
swap(&a, &b);
printf("after:%d %d\n", a, b);
return 0;
}
//int * x = &a; int *y = &b;
void swap(int * x, int * y)
{
int t;
t = *x;//a
*x = *y;
*y = t;
}
fun6.c
统计字符串中小写字母个数
#include
int str_fun(const char * p); // 加 const 表示不会修改 *p指向的数组中的值,更加严谨
int main(int argc, char *argv[])
{
// char *s = "hello" 指针直接指向字符串,不能改变,不能使用此种初始化方式
char s[] = "welcome2017Beijing";
int n;
n = str_fun(s);
printf("n=%d\n", n);
return 0;
}
int str_fun(const char * p) //char * p = s;
{
int num = 0;
while (*p != '\0') {//while (*p)
if (*p <= 'z' && *p >= 'a')
num++;
p++;
}
return num;
}
fun7.c
统计字符串中小写字母个数,并把字符串中小写字母转化为大写字母
#include
int str_fun(char * p);
int main(int argc, char *argv[])
{
char s[] = "welcome2017Beijing";
int n;
n = str_fun(s);
printf("n=%d %s\n", n, s);
return 0;
}
int str_fun(char * p) //char * p = s;
{
int num = 0;
while (*p != '\0') {//while (*p)
if (*p <= 'z' && *p >= 'a') {
num++;
*p -= ' '; //小写转大写 小写 - 空格 = 大写
}
p++;
}
return num;
}
fun8.c
函数中传递数组参数
计算一个一维整形数组中所有元素的和
#include
int array_sum(int data[], int n);
int main(int argc, char *argv[])
{
int a[] = {5, 9, 10, 3, 10};
int sum = 0;
sum = array_sum(a, sizeof(a)/sizeof(int));
printf("sum=%d\n", sum);
return 0;
}
int array_sum(int data[], int n) // int data[] = a; 不能把数组名赋给一个数组 error int * data = a; 若只有一个形参 int array_sum(int data[]) 且形参是数组名的时候,本质是一个指针变量
{//int n = sizeof(a)/sizeof(int); 如何传递数组 利用地复制传递方式,数组名
int ret = 0;
int i;
for (i = 0; i < n;i++) {
printf("%d\n", data[i]);
ret += data[i];
}
return ret;
}
fun9.c
函数中传递数组参数
计算一个一维整形数组中所有元素的和
#include
int array_sum(int * data, int n);
int main(int argc, char *argv[])
{
int a[] = {5, 9, 10, 3, 10};
int sum = 0;
sum = array_sum(a, sizeof(a)/sizeof(int));
printf("sum=%d\n", sum);
return 0;
}
int array_sum(int * data, int n) //int * data = a; 如何传递数组 利用地址传递方式,指针
{//int n = sizeof(a)/sizeof(int);
int ret = 0;
int i;
for (i = 0; i < n;i++) {
printf("%d\n", data[i]);
ret += data[i];
}
return ret;
}
fun10.c
删除字符串中的空格
用字符数组存字符串,字符数组传元素的时候,不需要传元素个数 和上面的程序形成对比
#include
void del_space(char * s1);
int main(int argc, char *argv[])
{
char s[] = " h a sdf g ";
puts(s);
del_space(s); //一维数组应该传数组名加元素个数 但字符数组比较特殊,内部可以通过指针遍历,传一个参数就可以 但形参使用的是指针形式需要注意
puts(s);
return 0;
}
void del_space(char * s1) // 利用指针 可以直接改变主函数字符数组中的内容,所以不需要有返回值,函数的数据类型就是 空
{
char * s2;
s2 = s1;
while (*s1) {
if (*s1 == ' '){
s1++;
}
else {
*s2 = *s1;
s1++;
s2++;
}
}
*s2 = '\0';
}
power.c
#include
double power(double x, int n)
{
double r = 1;
int i;
for (i = 1; i <= n; i++)
r *= x;
return r;
}
int main()
{
double x, ret;
int n;
printf("input:");
scanf("%lf%d", &x, &n);
ret = power(x, n);
printf("%lf %d = %lf\n", x, n, ret);
return 0;
}
power2.c
//#include
int scanf(const char *format, ...);
int printf(const char *format, ...);
double power(double, int);
int main()
{
double x, ret;
int n;
printf("input:");
scanf("%lf%d", &x, &n);
ret = power(x, n);
printf("%lf %d = %lf\n", x, n, ret);
return 0;
}
double power(double x, int n)
{
double r = 1;
int i;
for (i = 1; i <= n; i++)
r *= x;
return r;
}
函数专题2
digui1.c
编写递归程序 求 n!
#include
int fac(int n);
int main(int argc, char *argv[])
{
int n;
printf("input:");
scanf("%d", &n);
printf("%d\n", fac(n));
return 0;
}
int fac(int n)
{
if (n == 0 || n == 1)
return 1;
return n * fac(n-1); //递归就是自己调用自己
}
digui2.c
兔子繁殖问题 斐波那契数列
#include
int fib(int n);
int main(int argc, char *argv[])
{
int n = 1;
while (n <= 10) {
printf("%d ", fib(n)); // 循环打印出斐波那契数列前十个数
n++;
}
printf("\n");
return 0;
}
int fib(int n)
{
if (n == 1 || n == 2)
return 1;
return fib(n-1)+fib(n-2);
}
errorpfun.c
指针函数
改错:指针函数应该注意的问题是什么
#include
#include
char * getstring();
int main(int argc, char *argv[])
{
char * r;
r = getstring(); // str
printf("---%s---\n", getstring()); // 错误 函数的内存管理有问题,执行结果是否确定
(*r)++;
puts(r); // 错误 空间已经释放,无法再通过指针修改空间中的值
return 0;
}
char * getstring()
{
char str[20];
strcpy(str, "hello");
return str; //str是一个局部变量,存储在栈中,函数结束时,空间释放
}
fun1.c
#include
double power(double, int);
int main()
{
double x = 2, ret;
int n = 3;
ret = power(x, n);
printf("%lf %d = %lf\n", x, n, ret);
return 0;
}
double power(double x, int n)
{
double r = 1;
int i;
for (i = 1; i <= n; i++)
r *= x;
return r;
}
fun2.c
#include
double x = 2;
int n = 3;
double power();
int main()
{
// double x = 2;
// int n = 3;
double ret;
ret = power();
printf("%lf %d = %lf\n", x, n, ret);
return 0;
}
double power()
{
double r = 1;
int i;
for (i = 1; i <= n; i++)
r *= x;
return r;
}
fun3.c
#include
double power(double, int);
int main()
{
double x = 2;
int n = 3;
double ret;
printf("&x=%p &n=%p\n", &x, &n);
ret = power(x, n);
printf("%lf %d = %lf\n", x, n, ret);
return 0;
}
double power(double a, int b) //double a = x; int b = n;
{
double r = 1;
int i;
printf("&a=%p &b=%p\n", &a, &b);
for (i = 1; i <= b; i++)
r *= a;
return r;
}
fun4.c
#include
void swap(int x, int y);
int main()
{
int a = 10;
int b = 20;
printf("before:%d %d\n", a, b);
swap(a, b);
printf("after:%d %d\n", a, b);
return 0;
}
//int x = a; int y = b;
void swap(int x, int y)
{
int t;
t = x;
x = y;
y = t;
}
fun5.c
#include
void swap(int * x, int * y);
int main()
{
int a = 10;
int b = 20;
printf("before:%d %d\n", a, b);
swap(&a, &b);
printf("after:%d %d\n", a, b);
return 0;
}
//int * x = &a; int *y = &b;
void swap(int * x, int * y)
{
int t;
t = *x;//a
*x = *y;
*y = t;
}
fun6.c
#include
int str_fun(const char * p);
int main(int argc, char *argv[])
{
char s[] = "welcome2017Beijing";
int n;
n = str_fun(s);
printf("n=%d\n", n);
return 0;
}
int str_fun(const char * p) //char * p = s;
{
int num = 0;
while (*p != '\0') {//while (*p)
if (*p <= 'z' && *p >= 'a')
num++;
p++;
}
return num;
}
fun7.c
#include
int str_fun(char * p);
int main(int argc, char *argv[])
{
char s[] = "welcome2017Beijing";
int n;
n = str_fun(s);
printf("n=%d %s\n", n, s);
return 0;
}
int str_fun(char * p) //char * p = s;
{
int num = 0;
while (*p != '\0') {//while (*p)
if (*p <= 'z' && *p >= 'a') {
num++;
*p -= ' ';
}
p++;
}
return num;
}
fun8.c
#include
int array_sum(int data[], int n);
int main(int argc, char *argv[])
{
int a[] = {5, 9, 10, 3, 10};
int sum = 0;
sum = array_sum(a, sizeof(a)/sizeof(int));
printf("sum=%d\n", sum);
return 0;
}
int array_sum(int data[], int n) // int data[] = a;error int * data = a;
{//int n = sizeof(a)/sizeof(int);
int ret = 0;
int i;
for (i = 0; i < n;i++) {
printf("%d\n", data[i]);
ret += data[i];
}
return ret;
}
fun9.c
#include
double array_sum(double * data, double n);
double main(double argc, char *argv[])
{
double a[] = {5, 9, 10, 3, 10};
double sum = 0;
suum = array_suum(a, sizeof(a)/sizeof(double));
prdoublef("sum=%d\n", sum);
return 0;
}
double __sum(double * data, double n) //double * data = a;
{//double n = sizeof(a)/sizeof(double);
double ret = 0;
double i;
for (i = 0; i < n;i++) {data
prdoublef("%d\n", data[i]);
ret += data[i];
}
return ret;
}
fun10.c
#include
void del_space(char * s1);
int main(int argc, char *argv[])
{
char s[] = " h a sdf g ";
puts(s);
del_space(s);
puts(s);
return 0;
}
void del_space(char * s1)
{
char * s2;
s2 = s1;
while (*s1) {
if (*s1 == ' '){
s1++;
}
else {
*s2 = *s1;
s1++;
s2++;
}
}
*s2 = '\0';
}
funp1.c
函数指针 :存放函数地址 是一个指针
指针函数:是函数
#include
int add(int a, int b) {
return a+b;
}
int sub(int a, int b) {
return a-b;
}
int mul(int a, int b) {
return a*b;
}
int main(int argc, char *argv[])
{
int m = 10, n = 20;
int (* p)(int, int); // 函数指针声明 形参可以不写
p = add; // 函数指针赋值
//printf("%d\n", add(m, n));
printf("%d\n", (*p)(m, n)); // 函数指针调用 就是 函数名 的地方变成 *p 理解就相当于 普通变量 和 普通指针的关系
p = sub;
printf("%d\n", (*p)(m, n));
return 0;
}
funp2.c
函数指针数组
#include
int add(int a, int b) {
return a+b;
}
int sub(int a, int b) {
return a-b;
}
int mul(int a, int b) {
return a*b;
}
int main(int argc, char *argv[])
{
int m = 10, n = 20;
int (* p[2])(int, int); //int * p[3] 即在函数指针变量名处加一个数组维数
p[0] = add;
//printf("%d\n", add(m, n));
printf("%d\n", (*p[0])(m, n));
p[1] = sub;
printf("%d\n", (*p[1])(m, n));
return 0;
}
pfun1.c
对errorfun.c函数的修改:
1.全局变量
2.static变量
3.字符串常量
三种情况,存储在静态存储区,只有当程序结束后,内存空间才会释放
#include
#include
//char str[20]; // 延长函数中局部变量的使用时间 ,1.全局变量,如果是这样的话,main函数中可以直接使用,没有必要有子函数,所以也没有必要定义全局变量
char * getstring();
int main(int argc, char *argv[])
{
char * r;
r = getstring();
printf("---%s---\n", getstring());
//(*r)++; // 错误 若使用字符串常量,不能修改
puts(r);
return 0;
}
char * getstring()
{
//char str[20];//error
//static char str[20]; // 2. static变量
char * str = "hello"; // 字符串常量 是不能修改的
// strcpy(str, "hello");
return str;
}
pfun2.c
编写指针函数,删除一个字符串中的空格 ( 重 要 )
#include
#include
char * del_space(char * s);
int main(int argc, char *argv[])
{
//char * r;
char str[]= " how are you ";
char s[50], s2[50];
// r = del_space(str); // 对于一维数组来说,要传数组名和数据个数,但是对于字符串数组来说,只需要传数组名
// printf("---%s---\n", r);
//strcpy(s, del_space(str));
strcpy(s2, strcpy(s, del_space(str)));//m=n=k
puts(str);
puts(s);
puts(s2);
return 0;
}
char * del_space(char * s) //char * s = str;
{
char * r = s;
char * p = s;
while (*s) {
if (*s == ' ')
s++;
else {
*p = *s;
s++;
p++;
}
}
*p = '\0';
return r;
}
pfun3.c
实现字符串连接函数 ( 三种实现方式 )
#include
char * mstrcat(char * dest, const char * src);
int main(int argc, char *argv[])
{
//char * r;
char dest[50] = "welcome";
char src[] = "makeru";
puts(mstrcat(dest, src)); //可以直接使用strcat(); 加头文件 #include < string.h >
puts(dest);
return 0;
}
char * mstrcat(char * dest, const char * src)
{
// 进一步简化
char * r = dest; // 记录起始地址,返回值时使用
while (*dest++); // ++ 优先级比 * 高
dest--;
while (*dest++ = *src++); // 先将 src 的值赋给 dest , 然后再 ++
return r;
/* 代码简化后
char * r = dest;
while (*dest++); // while有分号 dest数组循环到数组末尾,由于++优先级高,循环最终指针指向 '\0' 停止,但 src 赋给dest的值要覆盖 '\0' 的值,后面的程序又使用到了 *dest++ 再次加到了 '\0' 后面一位,导致 '\0'也被复制到内部,所以,在while循环完后,要先 dest--
dest--;
while (*src) {
*dest++ = *src++;
}
*dest = '\0';
return r;
*/
/* 这部分注释可以实现字符串连接,思路清晰
char * r = dest;
while (*dest) {
dest++; // 注意:while(*dest++);(++优先级高于*,会先加)和 while( *dest ) dest++; 【先算*】 两种运算结果不同,
}
while (*src) {
*dest = *src;
dest++;
src++;
}
*dest = '\0';
return r;
*/
}
pfun4.c
整数转化为字符串
#include
char * itoa(int n); //参数和返回值,就是你给的和你想要的的关系 想要一个字符串,就定义一个字符指针函数
int main(int argc, char *argv[])
{
int n;
char * s; //main函数中没有字符串的存储空间
printf("input:");
scanf("%d", &n);
s = itoa(n);
puts(s);
return 0;
}
char * itoa(int n)
{
int r, i = 0, j;
static char p[50]; // 内存空间要一直保存
while (n) { // 先把所输入整数中每个字符取出来
r = n % 10;
n /= 10;
p[i] = r + '0'; // 数字和字符差48,将数字 +48 转化为字符 存入字符数组中
i++;
}
p[i] = '\0'; // 加字符串结尾
j = i-1;
i = 0;
while (i < j) { // 开始是从最后一位取值依次存入数组,通过循环实现数组逆序
r = p[i];
p[i] = p[j];
p[j] = r;
i++;
j--;
}
return p;
}
pfun5.c
和上面程序对比理解,main函数改变
#include
char * itoa(char *p, int n); // 传的是两个参数
int main(int argc, char *argv[])
{
int n;
char s[50], * r; // main函数中含有字符串可以存储的空间
printf("input:");
scanf("%d", &n);
r = itoa(s, n);
puts(r); // puts 打印字符串
puts(s);
return 0;
}
char * itoa(char *p, int n)
{
int r, i = 0, j;
//static char p[50]; // main函数中有可以存储字符串的空间,就不需要函数再另外设置字符串数组了
while (n) {
r = n % 10;
n /= 10;
p[i] = r + '0';
i++;
}
p[i] = '\0';
j = i-1;
i = 0;
while (i < j) {
r = p[i];
p[i] = p[j];
p[j] = r;
i++;
j--;
}
return p;
}
power.c
#include
double power(double x, int n)
{
double r = 1;
int i;
for (i = 1; i <= n; i++)
r *= x;
return r;
}
int main()
{
double x, ret;
int n;
printf("input:");
scanf("%lf%d", &x, &n);
ret = power(x, n);
printf("%lf %d = %lf\n", x, n, ret);
return 0;
}
power2.c
//#include
int scanf(const char *format, ...);
int printf(const char *format, ...);
double power(double, int);
int main()
{
double x, ret;
int n;
printf("input:");
scanf("%lf%d", &x, &n);
ret = power(x, n);
printf("%lf %d = %lf\n", x, n, ret);
return 0;
}
double power(double x, int n)
{
double r = 1;
int i;
for (i = 1; i <= n; i++)
r *= x;
return r;
}
qsort.c
调用C库中的qsort函数来实现整形数组的排序。
#include
#include
int compare(const void *, const void *);
int main(int argc, char *argv[])
{
int s[] = {89, 23, 10, 8, 7, 61}, n, i;
n = sizeof(s)/sizeof(int);
qsort(s, n, sizeof(int), compare);
for (i = 0; i < n; i++)
printf("%d ", s[i]);
puts("");
return 0;
}
int compare(const void * p, const void * q)
{
return (*(int *)p - *(int *)q); // 快速排序使用方法 :两个参数分别指向数组中的两个元素,令其相减,前面大于后面,就返回一个大于零的数,或小于 或等于
}
test.c
#include
#include
#define N 1
#define _DEBUG_
int main(int argc, char *argv[])
{
int m = 624;
m += 1;
#ifdef _DEBUG_
printf("%s %s, %d\n", __FILE__, __FUNCTION__, __LINE__);
#endif
m = sqrt(m);
printf("m=%d\n", m);
return 0;
}