• C【函数】


    1.常用API

    1.strcpy:#include

    char * strcpy ( char * destination, const char * source );
    
    1. int main()
    2. {
    3. char arr1[] = "bit";
    4. char arr2[20] = "###########";
    5. // bit\0########
    6. strcpy(arr2, arr1);
    7. printf("%s\n", arr2);
    8. //strcpy - string copy - 字符串拷贝
    9. //strlen - string length - 字符串长度有关
    10. return 0;
    11. }

    2.menset

    void * memset ( void * ptr, int value, size_t num );
    1. int main()
    2. {
    3. char arr[] = "hello world";
    4. memset(arr, '*', 5);
    5. printf("%s\n", arr);
    6. //***** world
    7. return 0;
    8. }

    3.参考网站

    cppreference.com

    2.自定义函数

    2.1 函数的组成

    1. ret_type fun_name(para1, * )
    2. {
    3. statement;//语句项
    4. }
    5. ret_type 返回类型
    6. fun_name 函数名
    7. para1 函数参数
    1. //定义函数
    2. //形参-形式参数-形式上参数
    3. int get_max(int x, int y)
    4. {
    5. if(x>y)
    6. return x;
    7. else
    8. return y;
    9. }
    10. int main()
    11. {
    12. int a = 10;
    13. int b = 20;
    14. //函数的使用
    15. int max = get_max(a, b);
    16. printf("max = %d\n", max);
    17. max = get_max(100, 300+1);
    18. max = get_max(100, get_max(3, 7));
    19. printf("max = %d\n", max);
    20. return 0;
    21. }

    2.2 交换函数

    1. void Swap1(int x, int y)
    2. {
    3. int tmp = 0;
    4. tmp = x;
    5. x = y;
    6. y = tmp;
    7. }
    8. void Swap2(int* pa, int* pb)
    9. {
    10. int tmp = 0;
    11. tmp = *pa;
    12. *pa = *pb;
    13. *pb = tmp;
    14. }
    15. int main()
    16. {
    17. int a = 10;
    18. int b = 20;
    19. //int tmp = 0;
    20. //
    21. printf("a=%d b=%d\n", a, b);
    22. //调用Swap1函数-传值调用
    23. Swap1(a, b);
    24. //调用Swap2函数
    25. Swap2(&a, &b);
    26. /*tmp = a;
    27. a = b;
    28. b = tmp;*/
    29. printf("a=%d b=%d\n", a, b);
    30. return 0;
    31. }

    3.函数的参数

    3.1 实际参数(实参)

    3.2 形式参数(形参)

    4.函数的调用

    4.1 传值调用

    函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参

    2.传址调用

    • 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
    • 这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操 作函数外部的变量。

    3.练习

    1. 写一个函数可以判断一个数是不是素数。

    1. //是素数返回1,不是素数返回0
    2. #include
    3. int is_prime(int n)//9
    4. {
    5. //2->n-1
    6. int j = 0;
    7. for(j=2; j<=sqrt(n); j++)
    8. {
    9. if(n%j == 0)
    10. return 0;
    11. }
    12. return 1;
    13. }
    14. int main()
    15. {
    16. //打印100-200之间的素数
    17. int i = 0;
    18. for(i=100; i<=200; i++)
    19. {
    20. //判断i是否为素数
    21. if(is_prime(i) == 1)
    22. printf("%d ", i);
    23. }
    24. return 0;
    25. }

    2. 写一个函数判断一年是不是闰年。

    1. //2. 写一个函数判断一年是不是闰年。
    2. int is_leap_year(int y)
    3. {
    4. if((y%4==0&&y%100!=0) || (y%400==0))
    5. return 1;
    6. else
    7. return 0;
    8. }
    9. int main()
    10. {
    11. int year=0;
    12. for(year=1000; year<=2000; year++)
    13. {
    14. //判断year是否为闰年
    15. if(1 == is_leap_year(year))
    16. {
    17. printf("%d ", year);
    18. }
    19. }
    20. return 0;
    21. }

    3. 写一个函数,实现一个整形有序数组的二分查找。

    1. //本质上arr是一个指针
    2. //3. 写一个函数,实现一个整形有序数组的二分查找
    3. int binary_search(int arr[], int k, int sz)
    4. {
    5. //算法的实现
    6. int left = 0;
    7. int right = sz-1;
    8. while(left<=right)
    9. {
    10. int mid = (left+right)/2;//中间元素的下标
    11. if(arr[mid] < k)
    12. {
    13. left = mid+1;
    14. }
    15. else if(arr[mid] > k)
    16. {
    17. right = mid-1;
    18. }
    19. else
    20. {
    21. return mid;
    22. }
    23. }
    24. return -1;
    25. }
    26. int main()
    27. {
    28. //二分查找
    29. //在一个有序数组中查找具体的某个数
    30. //如果找到了返回,这个数的下标。找不到的返回-1
    31. //
    32. int arr[] = {1,2,3,4,5,6,7,8,9,10};
    33. int k = 7;
    34. int sz = sizeof(arr)/sizeof(arr[0]);
    35. // 传递过去的是数组arr首元素的地址
    36. int ret = binary_search(arr, k, sz);
    37. if(ret == -1)
    38. {
    39. printf("找不到指定的数字\n");
    40. }
    41. else
    42. {
    43. printf("找到了,下标是:%d\n", ret);
    44. }
    45. return 0;
    46. }

    4. 写一个函数,每调用一次这个函数,就会将 num 的值增加1。

    1. int main()
    2. {
    3. int num = 0;
    4. Add(&num);
    5. printf("num = %d\n", num);//1
    6. Add(&num);
    7. printf("num = %d\n", num);//2
    8. Add(&num);
    9. printf("num = %d\n", num);//3
    10. return 0;
    11. }
    12. int main()
    13. {
    14. int len = 0;
    15. //1
    16. //len = strlen("abc");
    17. //printf("%d\n", len);
    18. //2
    19. printf("%d\n", strlen("abc"));
    20. return 0;
    21. }

    5.函数的嵌套调用和链式访问

    函数和函数之间可以根据实际的需求进行组合的,也就是互相调用的。

    5.1 嵌套调用

    1. #include
    2. void new_line()
    3. {
    4. printf("hehe\n");
    5. }
    6. void three_line()
    7. {
    8. int i = 0;
    9. for(i=0; i<3; i++)
    10. {
    11. new_line();
    12. }
    13. }
    14. int main()
    15. {
    16. three_line();
    17. return 0;
    18. }

    函数可以嵌套调用,但是不可以嵌套定义

    5.2 链式访问

    1. #include
    2. #include
    3. int main()
    4. {
    5. char arr[20] = "hello";
    6. int ret = strlen(strcat(arr,"bit"));//这里介绍一下strlen函数
    7. printf("%d\n", ret);
    8. return 0;
    9. }
    10. #include
    11. int main()
    12. {
    13. printf("%d", printf("%d", printf("%d", 43)));
    14. //结果是啥?
    15. //注:printf函数的返回值是打印在屏幕上字符的个数
    16. return 0;
    17. }

    6.函数的声明和定义

    6.1 函数声明

    6.2 函数定义

    7.函数递归

    7.1 递归的两个必要条件

    存在限制条件,当满足这个限制条件的时候,递归便不再继续。

    每次递归调用之后越来越接近这个限制条件

    7.2 练习




    1. int my_strlen(char* str)
    2. {
    3. int count = 0;
    4. while(*str != '\0')
    5. {
    6. count++;
    7. //str+1:表示指向下一个地址
    8. str++;
    9. }
    10. return count;
    11. }
    12. //递归的方法
    13. //把大事化小
    14. //my_strlen("bit");
    15. //1+my_strlen("it");
    16. //1+1+my_strlen("t");
    17. //1+1+1+my_strlen("")
    18. //1+1+1+0
    19. //3
    20. int my_strlen(char* str)//char* str:str数组的首地址
    21. {
    22. if(*str != '\0')//查看插入的数值的第一个是否为'\0'如果不是表示长度至少为1
    23. return 1+my_strlen(str+1);
    24. else
    25. return 0;
    26. }
    27. int main()
    28. {
    29. char arr[] = "bit";
    30. //int len = strlen(arr);//求字符串长度
    31. //printf("%d\n", len);
    32. //模拟实现了一个strlen函数
    33. //arr是数组,数组传参,传过去的不是整个数组,而是第一个元素的地址
    34. int len = my_strlen(arr);
    35. printf("len = %d\n", len);
    36. return 0;
    37. }

    7.递归和迭代

    1.求n的阶乘。(不考虑溢出)

    1. int Fac1(int n)
    2. {
    3. int i = 0;
    4. int ret = 1;
    5. for(i=1; i<=n; i++)
    6. {
    7. ret *= i;
    8. }
    9. return ret;
    10. }
    11. int Fac2(int n)
    12. {
    13. if(n<=1)
    14. return 1;
    15. else
    16. return n*Fac2(n-1);
    17. }
    18. int main()
    19. {
    20. //求n的阶乘
    21. int n = 0;
    22. int ret = 0;
    23. scanf("%d", &n);
    24. ret = Fac2(n);//循环的方式
    25. printf("%d\n", ret);
    26. return 0;
    27. }

    2.求第n个斐波那契数。(不考虑溢出)

    1. 斐波那契数列
    2. 1 1 2 3 5 8 13 21 34 55 ....
    3. 描述第n个斐波那契数的时候
    4. int count = 0;
    5. int Fib(int n)
    6. {
    7. if(n==3)//测试第3个斐波那契数的计算次数
    8. {
    9. count++;
    10. }
    11. if(n<=2)
    12. return 1;
    13. else
    14. return Fib(n-1)+Fib(n-2);
    15. }
    16. 50
    17. 49 48
    18. 48 47 47 46
    19. 47 46 46 45 46 45 45 44
    20. int Fib(int n)
    21. {
    22. int a = 1;
    23. int b = 1;
    24. int c = 1;
    25. while(n>2)
    26. {
    27. c = a+b;
    28. a = b;
    29. b = c;
    30. n--;
    31. }
    32. return c;
    33. }

    8.作业

    注意点:打印乘法表

    1. //1*1=1
    2. //2*1=2 2*2=4
    3. //3*1=3 3*2=6 3*3=9
    4. void print_table(int n)
    5. {
    6. int i = 0;
    7. for (i = 1; i <= n; i++)//控制行
    8. {
    9. int j = 0;
    10. for (j = 1; j <= i; j++)//控制列
    11. {
    12. printf("%d*%d=%-3d ", i, j, i*j);
    13. }
    14. printf("\n");
    15. }
    16. }
    17. int main()
    18. {
    19. int n = 0;
    20. scanf("%d", &n);
    21. print_table(n);
    22. return 0;
    23. }

    注意点2:将数组反转

    1. //将数组反转
    2. #include
    3. int my_strlen(char* str)
    4. {
    5. int count = 0;
    6. while (*str != '\0')
    7. {
    8. count++;
    9. str++;
    10. }
    11. return count;
    12. }
    13. //不使用库函数
    14. void reverse_string(char arr[])
    15. {
    16. int left = 0;
    17. int right = my_strlen(arr)-1;
    18. while (left
    19. {
    20. int tmp = arr[left];
    21. arr[left] = arr[right];
    22. arr[right] = tmp;
    23. left++;
    24. right--;
    25. }
    26. }
    27. //使用递归
    28. void reverse_string(char* arr)//abcdef
    29. {
    30. //数组的第一个元素
    31. char tmp = arr[0];//a
    32. //获取数组长度
    33. int len = my_strlen(arr);//f
    34. //将最后一个字母放入到第一位
    35. arr[0] = arr[len - 1];//【fdbcde】---->【a现在还没有放入数组中】
    36. //将最后一位的位置替换成'\0'
    37. arr[len - 1] = '\0';//【fbcde\0】
    38. if (my_strlen(arr+1) >=2)//将中间剩下的数组接着逆序
    39. reverse_string(arr+1);//arr首元素地址 arr+1:表示b的地址
    40. arr[len - 1] = tmp;//将a重新放回数组
    41. }
    42. int main()
    43. {
    44. char arr[] = "abcdefg";//fedcba
    45. reverse_string(arr);
    46. printf("%s\n", arr);
    47. return 0;
    48. }

    注意点3:写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和

    1. //写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和
    2. //
    3. //例如,调用DigitSum(1729),则应该返回1 + 7 + 2 + 9,它的和是19
    4. //
    5. //输入:1729,输出:19
    6. //DigitSum(1729)
    7. //DigitSum(172) + 1729%10
    8. //DigitSum(17) + 172%10 + 1729%10
    9. //DigitSum(1) + 17%10 + ...
    10. //1+7+2+9
    11. int DigitSum(unsigned int num)
    12. {
    13. if (num > 9)
    14. {
    15. return DigitSum(num / 10) + num % 10;
    16. }
    17. else
    18. {
    19. return num;
    20. }
    21. }
    22. int main()
    23. {
    24. unsigned int num = 0;
    25. scanf("%d", &num);//1729
    26. int ret = DigitSum(num);
    27. printf("ret = %d\n", ret);
    28. return 0;
    29. }

    注意点4:求n的k次方

    注意:要考虑到有负数的情况

    1. double Pow(int n, int k)
    2. {
    3. //n^k = n* n^(k-1)
    4. if (k < 0)//处理负数
    5. return (1.0 / (Pow(n, -k)));
    6. else if (k == 0)
    7. return 1;
    8. else
    9. return n*Pow(n, k - 1);
    10. }
    11. int main()
    12. {
    13. int n = 0;
    14. int k = 0;
    15. scanf("%d%d", &n, &k);
    16. double ret = Pow(n, k);
    17. printf("ret = %lf\n", ret);
    18. return 0;
    19. }
  • 相关阅读:
    MySQL中特别实用的几种SQL语句
    Linux 常用命令
    java-net-php-python-jsp员工时间管理系统查重PPT计算机毕业设计程序
    区块链软件开发中的虚拟机(virtual machine)
    如何使用 FaceIO 在 Vue.JS 中实现人脸识别?
    设计模式:访问者模式(C#、JAVA、JavaScript、C++、Python、Go、PHP)
    机器人中的数值优化|【三】无约束优化,拟牛顿法,共轭梯度法理论与推导
    106.(前端)分类管理显示增加值tag——使用elementui中的动态编辑标签搭建结构
    04.webpack中css的压缩和抽离
    SpringMVC:整合SSM框架
  • 原文地址:https://blog.csdn.net/m0_63077733/article/details/132892675