函数分为库函数和自定义函数,库函数是编译器自带的函数,自定义函数则是程序员本身定义的函数。程序员
#include <stdio.h> #include <string.h> int main() { char arr1[] = "bit"; char arr2[] = "###########"; strcpy(arr2, arr1); printf("%s\n", arr2); // 每一个字符串最后一位都是'\0',打印时遇到这个字符就会中止打印 return 0; }
程序实现了将一个字符串的内容覆盖进另外一个字符串,在写程序的时候须要注意的是,被覆盖的须要比须要拷贝的字符串长,不然就是一个bug。这就是头文件为string.h内部的一个函数,可以实现字符串的拷贝。算法
#include <stdio.h> #include <string.h> int main() { char arr[] = "hello world"; //将hello替换为***** //memset(目标地址,'要换进去的字符',数量); memset(arr, '*', 5); printf("%s\n", arr); return 0; }//主要是要学会在专业的网站上学会查询库函数的使用,zh.cppreference.com,cplusplus.com
msmset函数可以实现将内存里的某些段的字符屏蔽掉,或者修改成某个字符。也是头文件为string.h 的一个函数。对于库函数的学习最重要的仍是要认识到,要学会在函数库或者专业的网站上进行查询,[zh.cppreference.com, cplusplus.com ,进入网站对库函数进行查询,不必定要所有记住,可是要会查。数组
自定义函数有形参和实参,形参主要就是为了接受实参的量,或者指针变量。主要是为了在主函数外部实现某个单一的功能,一个函数能实现的功能越单一越好,更加简洁的实现某个功能,不须要每次实现某个功能都要输入对应的代码。ide
#include <stdio.h> int getmax(int x, int y) { return (x > y) ? (x) : (y); /*if (x > y) return x; else return y;*/ } int main() { int a = 20; int b = 30; int max = 0; max = getmax(a, b); printf("%d\n", max); return 0; }
在外部写出一个函数,实现两个数里取大的,属于传值调用,有返回值的函数,返回值为一个整形,因此用int定义函数,内部使用更简单的三目运算符。函数
#include <stdio.h> void Swap1(int x, int y) { x = x ^ y; y = x ^ y; x = x ^ y; }//事实证实,这个函数没法实现两个变量数值的交换 void Swap2(int* px, int* py) { *px = *py ^ *px; *py = *py ^ *px; *px = *py ^ *px; } int main() { int a = 10; int* pa = &a; int b = 30; int* pb = &b; printf("&a=%d &b=%d\n", pa, pb); printf("&a=%x &b=%x\n", pa, pb); printf("&a=%p &b=%p\n", pa, pb); printf("a=%d b=%d\n", *pa, *pb);//*解引用操做符,表示指针指向的数字, printf("a=%d b=%d\n", a, b); Swap1(a, b); //传值调用 只须要用到变量的值而无需改变外部的变量值的时候 //无需返回值的函数,函数类型为void,意为返回一个空值, printf("a=%d b=%d\n", a, b); Swap2(&a, &b); //传址调用 外部的变量须要在函数内部进行直接改变的时候 //存入指针变量而且能让指针变量正常使用的只能是取地址操做符取到的地址 printf("a=%d b=%d\n", a, b); return 0; }
第一次写出函数,运行以后发现没法实现变量的值的调换,仔细看过,并无发现什么问题,逐步调试事后,才发现,被调换了值的是被赋值了的形参,与真正须要调换值的变量并没有关系,在监视窗口中查询地址,发现形参和实参也是存在不一样的地址之下,最终在老师的指导之下,才明白,这是须要函数直接经过地址操纵变量,叫作传址调用, 形参的种类须要是指针变量,输入的形参也是取形参的地址。
另外我比较好奇指针到底会在不一样的类型之中会打印成什么样子,“printf("a=%d b=%d\n", pa, pb);”打印的是a和b的值,“printf("&a=%p &b=%p\n", pa, pb);”是将a和b的地址打印在指针变量中,是十六位十六进制的地址,“printf("&a=%x &b=%x\n", pa, pb);”讲地址打印在十六进制数中,值和printf("&a=%x &b=%x\n", pa, pb);同样,形式不一样,“printf("&a=%d &b=%d\n", pa, pb);”是直接用十进制打印出地址的值,可是值仍是和地址同样。学习
#include <stdio.h> #include <math.h> int Prime(int x) { int i = 0; for (i = 2; i <= sqrt(x); i++) { if (x % i == 0) { return 0; } } //if (i > sqrt(x)) return 1; } int main() { int a = 0; printf("请输入一个正整数:\n"); scanf("%d", &a); if (Prime(a)) printf("是一个素数\n"); else printf("不是一个素数\n"); return 0; }
判断一个数是否为素数的规则仍是很清晰的,看看这个数是否除了自身和1以外能被第二个数整除,不能就是一个素数。sqrt为求算术平方根,须要math.h的头文件,函数的调用为传值调用,返回一个整形。网站
#include <stdio.h> int Leap(int x) { if ((x % 4 == 0 && x % 100 != 0) || (x % 400 == 0)) { return 1; } else return 0; } int main() { int year = 0; printf("请输入一个年份:\n"); scanf("%d", &year); if (Leap(year)) printf("是闰年"); else printf("不是闰年\n"); return 0; }
仍是一个传值调用的函数,返回值为一个整形,将函数的返回值用于主函数if语句的判断条件。指针
#include <stdio.h> int binary_search(int arr[],int a,int s) { //算法的实现 int left = 0; int right = s - 1; int i = 0; while (left <= right) { int mid = (left + right) / 2; if (a > arr[mid]) { left = mid + 1; } else if (a < arr[mid]) { right = mid - 1; } else return mid; } return -1; } int main() { int arr[] = {1,2,3,4,5,6,7,8,9,10}; int a = 0; int sz = sizeof(arr) / sizeof(arr[0]); printf("请输入想要查找的数字:\n"); //若是找到了返回这个数的下标,若是没找到,返回-1 scanf("%d", &a); int ret = binary_search(arr, a, sz); //本质上传输到函数内部的是arr的地址,是一个指针变量,并非整个数组。 if (ret == -1) printf("没找到"); else printf("该数为arr[%d]\n",ret); return 0; }
须要注意的点,第一次在写程序过程当中并不能实现想要的效果,不管输入多少,函数都会返回一个相同的值,调试函数的时候在监视窗口才看到,形参在赋值的时候,只是获得了数组的第一个数,因此取地址,使得函数内部用指针访问数组,就可以访问到整个数组,而后数组的长度也就没法在函数内部求,因此直接将数组的长度做为一个参数加入函数之中,二分法也是了解的,所须要的功能得以实现。调试
#include <stdio.h> void Add (int* p) { *p = *p + 1; } int main() { int num = 0; printf("%d\n", num); Add(&num); //这是须要在函数内部改变自变量的值,传址调用; printf("%d\n", num); Add(&num); printf("%d\n", num); Add(&num); printf("%d\n", num); return 0; }
一个传值调用的无返回值函数,须要经过函数改变实参的值,因此要经过指针直接访问参量,改变参量的值。code
声明和定义是分开来放的,声明放在头文件中,函数的定义放在另外一个源文件中,共同构成一个实现某个功能的函数模块,在代码中须要使用到函数时,就将头文件的名称用双引号输入在#include 以后,下面就能调用在该目录之下的声明过的函数。函数的模块将会在函数的递归之中重点使用。