| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> C++知识库 -> C语言学习记录——? 函数和递归(1) -> 正文阅读 |
|
[C++知识库]C语言学习记录——? 函数和递归(1) |
库函数 IO函数 字符串操作函数 (比如strlen) 字符操作函数(比如把大写转小写) 内存操作函数(memset) 时间/日期函数(time) 数学函数(sqrt开平方) 其他库函数 怎样使用文档来学习库函数 strcpy,strlen char * strcpy (char * destination, const char * source)把源头拷贝到目的地. Copies the C string pointed by source into the array pointed by destination, including the terminating null charcter(and stopping at that point). To avoid overflows, the size of the array pointed by destination shall be long enough to contain the same C string as source (including the terminating null character), and should not overlap in memory with source. #include <string.h> int main() { char arr1[] = "bit"; char arr2[20] = "##########"; strcpy(arr2, arr1); printf("%s\n", arr2); //strcpy—字符串拷贝—string copy //strlen—string length—字符串长度有关 return 0; } 打印出来arr2就会是bit了,后面有\0 memset void * memset (void * ptr, int value, size_t num) Fill block of memory Sets the first num bytes of the block of memory pointed by ptr to? thr specified value(interpreted as an unsigned char) { char arr[] = "hello world"; memset(arr, '*', 5); printf("%s\n", arr); return 0; } memset里第一个是要改的对象,第二个为*,就是要改成什么,第三个是数量。但是只是把hello改成了星号,中间还会有个空格,结果是***** world。中间有一个空格。不过会发现一个问题,memset中第二个为int类型,星号并不是int类型。其实*在内存中存储时会存储ANCII值,所以并不会起冲突。 提一个之前strcpy一个问题,源头如果比目的地长度还长,那么就会溢出,要保证目的地字符串串长度足够长。 自定义函数 除了库函数,程序员自己也可以创建函数。 ret_type fun_name(para1, *) { statement;?? //语句项 } ret_type 返回类型 fun_name 函数名 para1???? 函数参数 大括号间是函数体。 get_max(int x, int y) { if(x > y) return x; else return y; } int main() { int a = 10; int b = 20; int max = get_max(a, b); printf("max = %d\n", max); return 0; 比较两个树的大小 另一个,交换两个整型变量的值 ?void Swap1(int x, int y) { int tmp = 0; tmp = x; x = y; y = tmp; } int main() { int a = 10; int b = 20; printf("a = %d\n b = %d\n", a, b); Swap1(a, b); printf("a = %d? b = %d\n", a, b); return 0; } void表示没有返回值。但是这样并没有交换。因为当监视整个过程时,会发现虽然xy已经被给了值,但是这个ab和xy的地址不一样,所以最后输出ab仍然是那个值 void Swap(int*pa, int*pb) { int tmp = 0; tmp = *pa; *pa = *pb; *pb = tmp; } int main() { int a = 10; int b = 20; printf("a = %d\n b = %d\n", a, b); Swap2(&a, &b); printf("a = %d? b = %d\n", a, b); return 0; } 函数的参数 实际参数(实参):真实传给函数的参数。实参可以是常量,变量,表达式,函数等。在进行调用时,它们都必须有确定的值,以便把这些值传送给形参。 形式参数(形参):形参是指函数名后括号中的变量,因为形参只有在函数被调用的过程中才实例化(分配内存单元),所以叫形参。形参当函数调用完成之后就自动销毁了。因此形参只在函数中有效。 形参比如,Swap程序中如果没有对a和b的使用,那么x和y也就没有使用空间,所以是形参,只有开始用这个函数时,才会实际存储到内存中。 当实参传给形参的时候,形参实例化后其实是实参的一种临时拷贝,对形参修改不会影响到实参。 函数调用 传值调用:函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参 Swap1就是一种传值调用,把ab的值传给xy。 传址调用:传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式;这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量。 Swap2是一种传址调用,把变量地址传过去。 区别:可以看到Swap1中,ab和xy地址不一样,只是值传过去,xy创立了独自的空间。而Swap2在这个函数内部可以操作函数外部的ab,需要将地址传过去。所以如果想改变函数外部的变量,要考虑传址。如果仅仅想要获得值,那么传值。 练习 1、写一个函数可以判断一个数是不是素数 #include <math.h> int wis_prime(int n) { int j = 0; for(j = 2; j <= sqrt(n); j++) { if(n % j == 0) return 0; } return 1; } int main() { int i = 0; for(i = 100; i <= 200; i++) { if(is_prime(i) == 1) printf("%d", i); } return 0; } 2、写函数判断是否是闰年 int is_leap_year(int y) { if((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0)) return 1; else return 0; } int main() { int year = 0; for(year = 1000; year <= 2000; year++) { if( 1== is_leap_year(year)) { printf("%d ", year); } } return 0; } 3、写函数,实现一个整形有序数组的二分查找。 int binary_search(int arr[], int k) { int sz = sizeof(arr) / sizeof(arr[0]); int left = 0; int right = sz - 1; while() { 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 ret = binary_search(arr, k); if (ret == -1) { printf("找不到指定的数字\n"); } else { printf("找到了,下标是: %d\n“, ret); } retrurn 0; } 但是这样就会出错,会打印出找不到指定的数字,如果监视binary函数,会发现,sz的值为1.因为这个程序把arr传过去,但是实际上传了第一个数字的地址,所以可以看出虽然写着int arr【】,但是这是一个指针变量,所以也就出来了1.现在改一下: int binary_search(int arr[], int k, int sz) { int left = 0; int right = sz - 1; while() { 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 ret = binary_search(arr, k); if (ret == -1) { printf("找不到指定的数字\n"); } else { printf("找到了,下标是: %d\n“, ret); } retrurn 0; } 这样就对了 4、写个函数,每调用一次这个函数,就会将num的值增加1. void Add(int* p) { (*p)++; } int main() { int num = 0; Add(&num) printf("num = %d\n", num); Add(&num) printf("num = %d\n", num); Add(&num); printf("num = %d\n", num); retturn 0; } 函数的嵌套调用和链式访问 嵌套调用:可以定义一个函数,在其他定义函数里也可以使用这个。 链式访问:把一个函数的返回值作为另一个函数的参数。 int main() { int len = 0; len = strlen("abc"); printf("%d\n, len); return 0; } 这样结果是3.可以简化: int main() { printf(“%d\n”, strlen("abc")); return 0; } 这也就是链式访问。 一些练习 int main() { printf("%d", printf("%d", printf("%d", 43))); return 0; } 结果是4321. 123个printf函数,需要用到返回值。查文档后,printf函数返回值类型是int类型,返回的是打印在屏幕上的字符个数。 函数的声明和定义 函数声明:函数在使用前都必须声明,告诉程序有这样一个函数。如同变量一样,int a = 1,这就是一种声明。 函数定义:刚才的自定义函数就是定义函数 比如: int Add(int x, int y); 告诉程序有一个Add程序,两个int类型的参数。不过写的时候,在用一个源文件时,更多使用函数定义,如同之前自定义函数一样,定义完后就可以使用,那么不需要再单独声明。 另一种方法,我们可以在另一个文件放上定义函数,然后在一个文件里引用,#include "add.h"在同一个文件里写函数,可能会混乱,当工作量大时。 结束。 |
|
C++知识库 最新文章 |
【C++】友元、嵌套类、异常、RTTI、类型转换 |
通讯录的思路与实现(C语言) |
C++PrimerPlus 第七章 函数-C++的编程模块( |
Problem C: 算法9-9~9-12:平衡二叉树的基本 |
MSVC C++ UTF-8编程 |
C++进阶 多态原理 |
简单string类c++实现 |
我的年度总结 |
【C语言】以深厚地基筑伟岸高楼-基础篇(六 |
c语言常见错误合集 |
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 10:35:53- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |