目录
----计算1/1+1/2+1/3..........+1/100
函数
函数分为:库函数 自定义函数
debug调试版本 release发布版本
库函数
io函数 输入输出函数 printf scanf getchar putchar
字符串操作函数 strcmp strlen
字符操作函数 toupper
内存操作函数 memcpy memcmp memset
时间/日期函数 time
数学函数
其他库函数
----strcpy
strcpy(arr1,arr2)
arr2内容放到arr1中
----memset内存设置
memset(arr,'x',5) 把arr前5个空间设置为x
自定义函数
函数名 返回值类型 函数参数
--------------------------------------------------
函数返回值类型 函数名(参数) //无返回值用void
{
语句项
}
----------------------------------------------------
int get_max(int a, int b)
{
if (a > b)
{
return a;
}
else
{
return b;
}
}
int main()
{
int a = 98;
int aa = 8;
int max = get_max(a, aa);
printf("%d", max);
return 0;
}
----交换两个变量的值(指针)(传址调用)
函数(传入的只是函数的值)
指针取地址改变外部变量
例:(交换两个变量的值)
void swp(int* x, int* y)//存放的是指针
{
int t = 0;
t = *x;
*x = *y;
*y = t;
}
int main()
{
int a = 8;
int b = 9;
printf("%d %d\n", a, b);
swp(&a, &b);//穿的是地址
printf("%d %d", a, b);
return 0;
}
参数类型
函数(实参)
实参:真实传递给函数的参数 可以是常量,变量,表达式,函数等
不管是什么,必须要有确定的值
定义部分
返回值类型 函数名(形参)
形参:函数调用完自动销毁
函数的调用----传值调用与传址调用
----判断一个数是不是素数(函数)
函数最好还是用返回值(不要打印)
//判断一个数是不是素数----函数
int panduan(int a)
{
int i = 0;
for (i = 2; i < a; i++)
{
if (a%i==0)
{
return 0;
}
}
return 1;//不要打印,功能细分
}
一个函数不写返回类型默认返回int类型
----二分查找(函数)传数组
//二分查找(函数)
int two(int a[],int k,int z)//传数组,形参定义时左半
{
int left = 0;
int right = z - 1;//为什么要在里面定义?
while (left <= right)
{
int mid = (left + right) / 2;
if (a[mid] ==k )
{
return mid ;
}
else if (k < a[mid])
{
right = mid - 1;
}
else if (k > a[mid])
{
left = mid + 1;
}
}
if (left > right)
{
return -1;
}
}
int main()
{
int arr[] = { 1,2,3,4,5,6,7,8,9,10};
int key = 0;//要查找的数
printf("输入要查找的数->");
scanf("%d", &key);
int sz = sizeof(arr) / sizeof(arr[0]);
int ii = two(arr, key, sz);
if(ii!=-1)
{
printf("找到了,下标[%d]",ii);
}
else
{
printf("找不到");
}
return 0;
}
sz 要传值过去原因
参数arr 传过去的只是数组第一个元素的地址 sizeof等操作不能正确进行
函数地嵌套使用和链式访问
嵌套使用
不能嵌套定义,能嵌套调用
int test1()
{
test3();
}
链式访问
把一个函数返回值作为另一个函数的参数
test1(test2())
printf("%d", printf("%d", printf("%d", 43)));
输出4321
printf()返回值是输出字符的个数
函数的声明和定义
编译器从前到后扫描
当函数定义在后面时,要先声明后使用
int main()
{
int a = 1;
int b = 9;
int add(int, int);//函数的声明
int c = add(a, b);
printf("%d", c);
return 0;
}
add(int a, int b)
{
return a + b;
}
函数的声明
函数类型 函数名(参数类型)(也可以加上参数名)
int add(int,int)
----函数的声明一般放在头文件中(分模块)
项目一般分模块
一个模块函数的声明放头文件中.h,函数的本体放.c中
调用时在主函数前
#include "函数名"
例:
计算器的加法模块
代码放add.c 声明放头文件add.h 调用在test.c中
#include " add.h"
卖代码,不想让别人知道代码内容(了解即可)
右击解决方案下面的,改为静态库
运行 到Debug路径下 .lib文件就是静态库
卖家使用
买了一个 .h .lib
.lib放项目路径下
----导入静态库
#pragma comment(lib,"sub.lib")
静态库名字
函数递归
函数直接或间接调用自己的一种方法
大事化小
----输入1234,输出1 2 3 4
思路: 先输出最高位的 一直/10 当<10 时%10 依次递归
void print_han(int a)
{
if (a > 9)
{
print_han(a / 10);
}
printf("%d ", a % 10);
}
int main()
{
int a = 0;
scanf("%d", &a);
print_han(a);
return 0;
}
递归两个必要条件
存在条件限制,当满足这个限制条件的时候,递归便不再继续
每次递归调用之后越来越接近这个限制条件
栈区、堆区
每次函数调用都要在栈区调用空间
递归太深就会栈溢出
----求字符串长度
编写函数,不用局部变量求字符串长度
--------用了局部变量,指针后移
思路:字符串结尾'\0'
*str 指针 str++指针后移
//求字符串长度
int my_strlen(char* arr)//相当于接受了一个元素的地址
{
int count = 0;
while (*arr != '\0')//这是字符,不是字符串可不用strcmp
{
arr++;//指针后移
count++;
}
return count;
}
int main()
{
char arr[20] = { 0 };
scanf("%s", arr);
int a=my_strlen(arr);//传入的是arr首元素的地址
printf("\n%d", a);
return 0;
}
----没用局部变量(函数递归)
思路:
限制条件:结尾是否为 \0
每次接近:指针后移(str+1)
int my_strlen(char * arr)
{
if (*arr!='\0')
{
return 1 + my_strlen(arr + 1);//不用arr++是因为其是先++后使用
}
else
{
return 0;
}
}
int main()
{
char arr[20] = { 0 };
scanf("%s", arr);
printf(" %d", my_strlen(arr));
return 0;
}
----求n的阶乘
限制条件:a>0
接近:a-1
//求n的阶乘
int jie(int a)
{
if (a > 0)
{
return a * jie(a - 1);
}
else
{
return 1;
}
}
int main()
{
int a = 0;
scanf("%d", &a);
printf(" %d",jie(a));
return 0;
}
----求第n个斐波那契数列
1 1 2 3 5 后面的数等于前面两个数的和
限制条件:第一个 第二个为1
接近:n-1
//斐波那契数列
int feibo(int a)
{
if (a == 1 ||a==2)
{
return 1;
}
else
{
return feibo(a - 1) + feibo(a - 2);
}
}
int main()
{
int a = 0;
scanf("%d", &a);
printf("第%d个斐波那契数是%d", a, feibo(a));
return 0;
}
效率低,大数要计算好几分钟
--------不用递归 斐波那契
1 1 2 3 5 8 13 21 34 55
| | |
a b c
原理:a=1 b=1
c=a+b 一直向前推进
//斐波那契数列(不用递归 效率高)
int feibo(int n)
{
int a = 1;//前面的指针
int b = 1;//后面的
int c = 1;
while (n > 2)//n为1,2时.c为1
{
c = a + b;
a = b;
b = c;//前移
n--;//控制次数
}
return c;
}
int main()
{
int n = 0;
scanf("%d",&n);
printf("第%d个斐波那契数是%d", n,feibo(n));
return 0;
}
n-- 原因:当n为3时,计算一次 n>3时,需要计算n-2次
正好n>2退出
数字太大会错,(因为整型下放不下这么大的数)
----1到100的整数中间有多少个9
//1到100有多少个整数9
int main()
{
int count = 0;
int i = 0;
for (i = 1; i <= 100; i++)
{
if (i%10==9)//个位数是9
{
count++;
}
if (i/10==9)//十位是9
{
count++;
}
}
printf("%d", count);
return 0;
}
----计算1/1+1/2+1/3..........+1/100
//计算1/1+1/2+....1/100
int main()
{
int i = 0;
double he = 0;
for (i = 1; i <= 100; i++)
{
he = he + 1.0 / i;//1.0防止整数除法结果只有整数
}
printf("%lf", he);
return 0;
}
加减交替
int main()
{
int i = 0;
double he = 0;
int flag = 1;
for (i = 1; i <= 100; i++)
{
he = he + 1.0*flag / i;//1.0防止整数除法结果只有整数
flag = -flag;
}
printf("%lf", he);
return 0;
}
加上一个flag
----求10个数中最大值
//求十个数中的最大值
int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
int i = 0;
int max = arr[0];//
for (i = 0; i <= 9; i++)
{
if (arr[i] > max)
{
max = arr[i];
}
}
printf("%d", max);
return 0;
}
注意比较数max要用数组内的数(如果max开始就比数组内所有数都大,比较失败)
----九九乘法表%2d
int main()
{
int i = 1;
int ii = 1;
for (i = 1; i <= 9; i++)
{
for (ii = 1; ii <= i; ii++)
{
printf("%d*%d=%d ", i, ii, i * ii);
}
printf("\n");
}
return 0;
}
要<=i 防止1*9 9*1 等同时存在
%2d(强制打印2个,不够用空格代替)
%2d(同上,不过不得空格在右边)
打印乘法口诀表(函数,行列自己指定)
void print_c(int n)
{
int i = 0;
int ii = 0;
for (i = 1; i <= n; i++)
{
for (ii = 1; ii <= i; ii++)
{
printf("%d*%d=%-2d ", ii, i, i * ii);
}
printf("\n");
}
}
int main()
{
int n = 0;
scanf("%d", &n);
print_c(n);
return 0;
}
----字符串逆序
--------正常
//字符串逆序实现
int my_sizeof(char* str1)
{
int count = 0;
while (*str1!='\0')
{
count++;
str1++;
}
return count;
}
void reverse_str(char* str)
{
int left = 0;
int right = my_sizeof(str)-1;
while (left <= right)
{
char tmp = str[right];
str[right] = str[left];
str[left] = tmp;
left++;
right--;
}
printf("%s", str);
}
int main()
{
char arr[] = "abcdefgh";
reverse_str(arr);//reserve是保留;reverse是相反
return 0;
}
--------递归
a b c d e f
传入的指针指向a 交换af f处暂时放上\0(递归为一个字符串) 递归 f处放上f的值
//字符串逆序
int my_strlen(char* ar)
{
int count = 0;
while (*ar != '\0')
{
ar++;
count++;
}
return count;
}
void re_str(char* str)
{
int sz = my_strlen(str);
char tmp = *(str);
*str = *(str + sz - 1);//最后一个元素
*(str + sz - 1) = '\0';
if (my_strlen(str+1) != 0)
{
re_str(str + 1);
}
*(str + sz - 1) = tmp;
}
int main()
{
char arr[] = "abcdefg";
re_str(arr);
printf("%s", arr);
return 0;
}
----输入一个非负数 计算他的各位数字之和
//输入非负数字计算各位之和
int sum(int a)
{
if (a>9)
{
return sum(a / 10)+(a%10);
}
return a;
}
int main()
{
int a = 0;
scanf("%d", &a);
printf("%d", sum(a));
return 0;
}
----题的零碎知识点
return只能返回一个数 return1,2 起不到效果
函数必须先声明,再使用
exec((v1,v2),(v2,v3),v5,v6)中实参的个数是
--------逗号表达式
(v1,v2)这叫做逗号表达式 从左到右计算,最后一个表达式的结果是表达式的值