目录
接上次 函数初步了解(1)http://t.csdn.cn/qfbq8
1.练习
//写一个函数,实现一个整型有序数组的二分查找
<1>普通方法
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int i = 0;
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 7;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
if (k == arr[i])
{
printf("找到了,下标是%d\n", i);
break;
}
}
if (i == sz)
printf("找不到\n");
return 0;
}
<2>优化——二分法
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 7;
int sz = sizeof(arr) / sizeof(arr[0]);
int left = 0;
int right = sz - 1;
while (left <= right)
{
int mid = (left + right) / 2;
if (arr[mid] < k)
{
left = mid + 1;
}
else if (arr[mid] > k)
{
right = mid - 1;
}
else
{
printf("找到了,下标是%d\n", mid);
break;
}
}
if(left > right)
{
printf("找不到\n");
}
return 0;
}
<3>函数
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int binary_search(int arr[], int k, int sz)
{
int left = 0;
int right = sz - 1;
while (left<=right)
{
int mid = (left + right) / 2;
if (arr[mid] < k)
{
left = mid + 1;
}
else if (arr[mid] > k)
{
right = mid - 1;
}
else
{
return mid;
}
}
return -1;
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
int k = 7;
int sz = sizeof(arr) / sizeof(arr[0]);
int pos = binary_search(arr, k,sz);
if (-1 == pos)
printf("找不到\n");
else
printf("找到了,下标是%d\n", pos);
return 0;
}
//写一个函数,每次调用时,num都加一
<1>普通方法
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int Add(int n)
{
return n + 1;
}
int main()
{
int num = 0;
num = Add(num);
printf("%d\n", num);
num = Add(num);
printf("%d\n", num);
num = Add(num);
printf("%d\n", num);
return 0;
}
<2>指针
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int Num(int* p)
{
*p = *p + 1;
}
int main()
{
int num = 0;
Num(&num);
printf("%d\n", num);
Num(&num);
printf("%d\n", num);
Num(&num);
printf("%d\n", num);
return 0;
}
函数的返回类型什么都不写时,默认返回的是int类型,返回最后一条代码的字符个数
总结:好好写代码,不要图方便,该加上的不要漏!!!
2.函数的嵌套调用和链式访问
1)嵌套调用
函数可以嵌套调用,但是不能嵌套定义。
2)链式访问
像一个链条一样把参数串起来,将一个函数的返回值作为另一个函数的参数。
printf函数返回的是打印在屏幕上字符的个数
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
printf("%d", printf("%d", printf("%d", 43)));
return 0;
}
3.函数的声明和定义
函数的定义也是一种特殊的声明;
全局变量不初始化的话默认是值是零;
名字可以不给,如 ADD(int,int);
自己写的用include"add.h",即 " " 而不是 < >;
有定义时前面就是声明,没定义时就算没有赋值前面也是定义;
函数的声明一般都放在头文件中,函数的定义和实现一般都放在源文件中;
拆成源文件头文件的优势:
1.模块化开发 :比如若想创建一个计算器,加减乘除代码可分配给不同的程序员写,分工合作
2.代码的隐藏 :维护自身权益和知识产权(一天一个赚钱小技巧哈哈)
4.函数递归
定义:程序调用自身的编程技巧称为递归(recursion),即直接或间接调用自己,
少量程序就可描述出解题过程所需要的多次重复计算,大大减少程序的代码量。
递——递推 , 归——回归
主要思考方式:把大事化小
两个必要条件:1)存在限制条件,当满足这个条件时,递归便不再继续;
2)每次递归调用后越来越接近这个限制条件。
//史上最简单(但错误的)递归:
#include<stdio.h>
int main()
{
printf("hehe\n");
main();
}
——>最终程序会崩掉(栈溢出)
内存区域: 栈区 堆区 静态区
每一次调用函数,都会为本次函数在内存的栈区上开辟一块内存空间。
这里来一个小插曲~
程序员的问答社区:
segmentfault (国内)思否
stackoverflow (国外)英文提问英文回答
//接受一个整型值(无符号),按照顺序打印它的每一位
<1>普通方法
想打印几位数就得输入几段重复的代码,繁琐缓慢。
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
int main()
{
int num = 0;
int a, b, c, d, e;
scanf("%d", &num);
e = num % 10;
num = num / 10;
d = num % 10;
num = num / 10;
c = num % 10;
num = num / 10;
b = num % 10;
num = num / 10;
a = num % 10;
num = num / 10;
printf("%d %d %d %d %d\n", a, b, c, d, e);
return 0;
}
<2>函数递归
无论想打印几位数都可以,简洁快速。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void Print(unsigned int n)
{
if (n > 9)
{
Print(n / 10);
}
printf("%d ", n % 10);
}
int main()
{
unsigned int num = 0;
scanf("%u", &num);
Print(num);
return 0;
}
//编写函数不允许创建临时变量,求字符串长度
即模拟实现strlen的功能
注:数组名是数组首元素的地址
str ++ :字符指针+1,向后跳1个字符
int ++:向后跳一个整型,即四个字节
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int my_strlen(char* str)
{
if (*str != '\0')
return 1 + my_strlen(str + 1);
else
return 0;
}
int main()
{
char arr[] = "hehe";
int len = my_strlen(arr);
printf("%d\n", len);
return 0;
}
FINISH~~
emmmm......总的来说,递归对我来说还是有点难度的,属于看得懂代码但是不会写的那种。脑子:我悟了我会了;手:不你不会……累了累了……还是题见少了写少了,要多多练习呀。
加油加油!!!