一、函数的定义和调用1、格式注意定义的函数不能写在 main 里面。函数里面不能再写其他函数。应用时直接写函数名加括号。eg:①//#include stdio.h //void look() //{ // printf(打开手机\n); // printf(打开小视频\n); // printf(拨动\n); // printf(赏析\n); //} //int main() //{ // look(); // printf(吃一块饼干\n); // look(); // return 0; //}注意函数定义了不会主动运行因为运行时会去找 main 这个主入口我们要在 main 中调用我们定义的这个函数②计算1020的和//#include stdio.h //void sum() //{ // int a 10; // int b 20; // printf(%d, a b); //} //int main() //{ // sum(); // return 0; //}①当函数需要计算的参数不明确时我们可以把参数定义在小括号中。此时只定义不给值在调用时会根据实际情况传入不同的值。②函数定义的小括号中叫形式参数即形参形参间用逗号隔开。函数调用的小括号中叫实际参数即实参。形参与实参必须一一对应。eg:①定义一个函数求两数之和并把结果输出到控制台上//#include stdio.h //void sum(int num1,int num2) //{ // int sum num1 num2; // printf(%d\n, sum); //} //int main() //{ // sum(7,8); // sum(10, 20); // // return 0; //} 注注意上面的sum是函数名称下面的sum是变量名②定义一个函数打印多次“我想吃饭”打印的次数由传入的参数决定//#include stdio.h //void a(int b) //{ // for (int c 1;c b;c) // { // printf(我想吃饭\n); // } //} //int main() //{ // a(100); // return 0; //}3、带有返回值的函数最终完整格式原来格式当题目复杂时比如调用只需拿到函数计算的结果进行比较时我们需要换一种方式将最后的值不是打印出来而是交给调用值→完整格式eg:注意返回值类型与返回值对应返回的调用值需要用一个变量去吸收.定义函数的终极绝招问三个问题1. 我定义函数是为了干什么确定函数体。2. 我干这件事情需要什么才能完成确定形参。3. 我干完了调用处是否需要继续使用确定返回值类型。eg:①小明考试成绩基础题93分附加题10分。小红考试成绩基础题87分附加题9分。问谁的分高//#include stdio.h //int score(int a, int b) //{ // int score a b; 注两个int score意义不同 // printf(%d\n, score); // return score; //} //int main() //{ // int c score(93, 10); // int d score(87, 9); // if (c d) // { 调用方式用变量去接收函数的结果 // printf(小明成绩更高); printf(占位符”函数的调用 // } // else if (d c) // { 函数的好处提高代码复用性提高代码可维护性 // printf(小红成绩更高); // } // else // { // printf(他们一样高); // } // return 0; //}②//#includestdio.h //int sum(int a, int b, int c) //{ // int sum a b c; // return sum; //} //int main() //{ // int equal1 sum(10, 20, 15); // int equal2 sum(20, 30, 17); // int equal3 sum(19, 17, 20); // int equal4 sum(23, 21, 19); // int max_money equal1; // int max_month 1; // if (equal2 max_money) // { // max_money equal2; // max_month 2; // } //if (equal3 max_money) // { // max_money equal3; // max_month 3; // } // if (equal4 max_money) // { // max_money equal4; // max_month 4; // }// printf(第%d个季度营业额最高\n, max_month); // return 0; // //}函数的注意事项1. 函数不调用就不执行。2. 函数名不能重复。3. 函数与函数之间是平级关系不能嵌套定义。4. return 下不能写代码。5. 自未定义的函数写在 main 函数下面需要在上方声明。6. 函数返回值类型为 void表示没有返回值return 可以省略不写。如果书写了 return后面不跟具体的数据仅表示结束函数4、C语言中常见的函数C语言会把这些函数放入不同的头文件中使用#include math此类型eg:①不同头文件中函数使用//#include stdio.h //#include time.h //int main() //{ // long long res time(NULL); // printf(%lld\n, time); 形参表示获取的当前值是否需要在其他地方进行存储一 //} 般来讲不需在其他地方进行存储写NULL //#include stdio.h //#include math.h //int main() //{ // double a pow(2,3); // printf(%lf\n, a); // double b sqrt(8); // printf(%lf\n, b); // double c ceil(3.1); // printf(%lf\n, c); // double d floor(3.1); // printf(%lf\n, d); // double e abs(-1); // printf(%lf\n, e); // return 0; //}②获取随机数的函数//#includestdio.h //#includestdlib.h 随机数头文件//#includetime.h //int main() //{ //srand(time(NULL)); 设置种子// for (int i 1;i 10;i) // { //int num rand() % 100 1;// printf(%d\n, num); // } // // // return 0; //}注意种子不变随机数结果是固定的所以用一个变化的量充当种子即时间。随机数的范围没有办法自行指定绝招是用于生产任意范围之内的随机数1. 把这个范围变成包头不包尾、包左不包右的。2. 拿着尾巴剪开头。3. 修改代码。int numrand()%1001二、递归函数递归是一种解决问题的方法1、递归就是函数自己调用自己2、递归的思想把一个大型复杂问题层层转化为一个与原题相似但规模较小的子问题来求解直到子问题不能再拆分递归就结束了。所以递归的思考方式就是把大事化小的过程。递归中的“递”就是递推的意思“归”就是回归的意思。3、递归的限制条件递归在书写中有两个必要条件1. 递归存在终止条件当满足这个终止条件时递归便不再继续。2. 每次递归调用之后越来越接近这个终止条件。eg:①求N的阶乘//#include stdio.h //int Fac(int n) //{ // if (n 0) // { //return1; return把后面的值交给调用处并转化为一个与原问题相似、但 // } 较小的子问题。 // else // { //return Fac(n - 1) * n; // } //} //int main() //{ //int n; // scanf(%d, n); // int aFac(n); // printf(%d\n, a); // return 0; //}②顺序打印一个整数的每一位//#include stdio.h //void print(int n) //{ //if (n 9) // { // print(n / 10); // } // printf(%d, n % 10);// //} //int main() //{ // int n; // printf(请你输入一个数字:\n); // scanf(%d, n); //print(n); 没有返回值定义一个变量去接纳。// return 0; // //}3、递归与迭代eg:求N的阶乘法一递归法。 法二循环。递归函数调用的过程中涉及一些运行的开销循环及迭代当问题非常复杂时难以用迭代的方式实现此时递归实现的简洁性便可以补偿它所带来的运行时开销。eg:斐波那契数列法一//#include stdio.h //int Fib(int n) //{ // if (n 2) // { // return 1; // } // else // { // return Fib(n - 1) Fib(n - 2); // } //} //int main() //{ // int n; // while (1) // { // printf(请输入一个数字:\n); // scanf(%d, n); // int a Fib(n); // printf(相应的斐波那契数字为:%d\n, a); // } // return 0; // //} 法二: #include stdio.h int Fib(int n) { int a 1; int b 1; int c 1; while(n3) { c a b; a b; b c; n--; } return c; } int main() { int n; printf(请输入一个数字:\n); scanf(%d, n); int c Fib(n); printf(%d\n, c); return 0; }二、数组1、定义存储一批同类型数据的地方同类型数据有隐式转换取值范围小的赋值给取 · 值范围大的也可以2、格式3、特点①连续的空间。②维数组一旦定义长度不可变且写在开头。//#include stdio.h //int main() //{ // /*int arr[80]; // double hight[50]; // int a[3];*/4、数组的初始化定义数组时第一次给数组赋值。格式细节1. 长度省略数据值的个数就是数组长度。2. 长度未省略数据值的个数小于等于长度。未赋值部分有默认值eg:/*int arr1[5] { 17,18,19,18,19 }; // int hight[1] { 1.68 };5、元素访问....获取、修改①索引是数组的一个编号也叫角标、下标、编号。特点从 0 开始的连续加 1 不 间断。②获取变量 数组名[索引]。③修改数组名「索引」数据值eg:/*int arr[5] { 1,2,3,4,5 };*/ // /*int a arr[0]; // int b arr[2]; // int c arr[4]; // printf(%d\n, a b c); // arr[4] 10;*/6、数组遍历依次获取数组中的每一个元素。eg:/*int arr[5] { 1,2,3,4,5 };*//*for (int i 0;i 4;i) // { // arr[i]; // printf(%d\n, arr[i]); // }*/7、内存中的变量数组内存软件运行时用来临时存储数据8.数组中的常见问题9.数组的算法题练习①求最值已知数组元素为 [33,5,22,44,55]请找出数组中的最大值并打印在控制台/#include stdio.h //int main() //{ // int arr[] { 33,5,22,44,55}; // int len sizeof(arr) / sizeof(int); // int max arr[0]; // for (int i 1;i len;i)注max的默认值不可以写为0// {如果数组中的数都为负数循环后最大值为0// if (max arr[i])所以 max 的默认值一定要是数组中已经存在的数// {一般把0索引当默认值// max arr[i]; // } // } // printf(%d\n, max); // // return 0; //}②/遍历数组求和基础版 // 生成10个1~100之间的随机数存入数组 //#include stdio.h //int main() //{ // int arr[10] {0}; // int len sizeof(arr) / sizeof(int); // srand(time(NULL)); // for (int i 0;i len;i)注len表示长度即元素个数// { // int num rand() % 100 1; // arr[i] num; // printf(%d\n, num); // } // int sum 0; // for (int i 0;i len;i) // { // sum sum arr[i]; // } // printf(%d\n,sum); // // return 0; //}③////遍历数组求和升级版生成 10 个 1~100 之间的随机数存入数组要求数据不能重复 //// 1、求出所有数据的和。2、求出所有数据的平均数。3、统计有多少个数据比平均值小。 //#include stdio.h //#include time.h //#include stdlib.h //int contains(int arr[], int len, int num) //{ // for (int i 0;i len;i) // { // if (arr[i] num) // { // return 1; // } // }////问题一为什么不能写 else return 0一触发return就结束//return 0; //}//int main() //{ // srand(time(NULL)); // int arr[10] { 0 }; // int len sizeof(arr) / sizeof(int); // for (int i 0;i len;) // { //int num rand() % 100 1;// int flag contains(arr, len, num); //if (!flag) // { // arr[i] num; // i; // printf(%d\n, num); // // } //// } // /*for (int i 0;i len;i) // { // printf(%d\n, arr[i]); // }*/ // int sum 0; // for (int i 0;i len;i) // { // sum sum arr[i]; // } // printf(%d\n, sum); // int sve sum / len; // printf(%d\n, sve); // int count0; // for (int i 0;i len;i) // { // if (arr[i] sve) // { // count; // } // } // printf(%d\n, count); // // return 0; //}④////反转数组要求键盘录入 5 个数据并存入数组完成以下需求1. 遍历数组2. 反转数组 //#include stdio.h //void printArr(int arr[], int len) //{ // for (int i 0;i len;i) // { // printf(%d\n, arr[i]); // } //} //int main() //{ // int arr[5] { 0 }; // int len sizeof(arr) / sizeof(int); // for (int i 0;i len;i) // { // printf(请录入第%d个数字\n, i 1); // scanf(%d, arr[i]); // } // printArr(arr, len); // int i 0; // int j len - 1; //while (i j) // { // int num arr[i]; // arr[i] arr[j]; // arr[j] num; // i; // j--; // }// printArr(arr, len); // return 0; //}⑤打乱数组中的数据需求定义一个数组存入1~5要求打乱数组中所有数据的顺序/#include stdio.h //#include time.h //#include stdlib.h //int main() //{ // int arr[] { 1,2,3,4,5 }; // int len sizeof(arr) / sizeof(int); // srand(time(NULL)); // for(int i0;ilen;i) // { // int num rand()%len; // int temp arr[i]; // arr[i] arr[num]; // arr[num] temp; // } // for (int i 0;i len;i) // { // printf(%d\n, arr[i]); // } // return 0; //}10.常见算法1️⃣查找算法:①基本查找核心思路就是从数值中的0开始依次往后查找。如果找到了就会返回数据对应的索引如果没有找到就会返回-1eg:///数组的基本查找 //#include stdio.h //int order(int arr[], int len, int num) //{ // for (int i 0;i len;i) // { // if (arr[i] num) // { // return i; // } // //为什么不可以写成else要把return -1写在for循环的外面 // /*else // { // return -1; // }*/ // // } //return -1; //循环结束后都无符合条件的才返回负一// //} //int main() //{ // int arr[] { 2,23,43,55,65 }; // int len sizeof(arr) / sizeof(int); // int num 55; // int temp order(arr, len, num); // printf(%d\n, temp); // return 0; // // //}2️⃣二分查找折半查找前提条件数组中的数据必须是有序的核心逻辑每次排除一半的查找范围。min 和 max 表示当前要查找的范围mid 是在 min 和 max 中间的。1. 如果查找的元素在 mid 左边缩小范围时 min 不变max mid - 1。2. 如果查找的元素在 mid 右边缩小范围时 max 不变min mid 1。eg://#include stdio.h //int binarySearch(int arr[], int len, int num) //{ // int min 0; // int max len - 1; // //二分查找 // /*while (min max) // { // int mid (min max) / 2; //if (arr[mid] num) // { // min mid 1; // } // else if (arr[mid] num) // { // max mid - 1; // } // else // { // return mid; // }// } // return -1;*/ // //插值查找 // while (min max num arr[min] num arr[max]) // { // // 防止除以 0 的错误如果区间内所有数字都一样 // if (arr[max] arr[min]) // { // if (arr[min] num) return min; // else break; // } // // // 插值查找核心公式 // // 注意必须先乘后除防止类似 33/44 变成 0 导致死循环。 //int mid min (num - arr[min]) * (max - min) / (arr[max] - arr[min]);// // // 打印每次计算的mid方便你观察过程 // printf(当前 min%d, max%d, 计算出的 mid%d\n, min, max, mid); // // if (arr[mid] num) // { // min mid 1; // } // else if (arr[mid] num) // { // max mid - 1; // } // else // { // return mid; // 找到了返回数组下标 // } // } // return -1; // 没找到 // //} //int main() //{ // int arr[] { 23,34,45,56,67 }; // int len sizeof(arr) / sizeof(int); // int num 34; // int temp binarySearch(arr, len, num); // printf(%d\n, temp); // return 0; // //}3️⃣分块查找分块原则 1前一块中的最大数据小于后一块的所有数据。原则 2块的数量一般等于数字个数的开根号。11.排序算法1️⃣冒泡排序A. 相邻的数据两两比较小的放前大的放后。B. 第一轮比较完后最大值已经确定。第二轮可以少循环一次后面以此类推。eg:/将35214进行从小到大的冒泡排序 //#include stdio.h //int main() //{ // int arr[] { 3,5,2,1,4 }; // int len sizeof(arr) / sizeof(int); // 外层循环控制比较的趟数len 个数需要 len-1 趟 // for (int i 0;i len-1;i) // { //内层循环控制每趟比较的次数小于 LEN-1-i是为了防止 arr[j1] 越界 // for (int j 0;j len-1-i;j)// { // if (arr[j] arr[j 1]) // { // int num arr[j]; // arr[j] arr[j 1]; // arr[j 1] num; // } // } // // } // for (int i 0;i len;i) // { // printf(%d\n, arr[i]); // } // return 0; //}2️⃣选择排序从 0 索引开始拿着每一个索引上的元素跟后面的元素依次比较小的放前面大的放后面以此类推eg:////将35214从小到大选择排序 //#include stdio.h //int main() //{ // int arr[] { 3,5,2,1,4 }; // int len sizeof(arr) / sizeof(int); // for (int i 0;i len - 1;i) // { // for (int j i 1;j len;j) // { // if (arr[i] arr[j]) // { // //位置交换 // int num arr[i]; // arr[i] arr[j]; // arr[j] num; // } // } // // } // //遍历数组 // for (int i 0;i len;i) // { // printf(%d\n, arr[i]); // } // return 0; //}12.二维数组.eg:/#include stdio.h //int main() //{ // int arr[3][5] { 0}; // /*int arr[3][5] { { 1,2 },{ 3,4 } { 5,6 } };*/ // int len sizeof(arr) / sizeof(arr[0]); // int len2 sizeof(arr[0]) / sizeof(arr[0][0]); // for (int i 0;i len;i) // { // for (int j 0;j len2;j) // { ////为什么每个数字要空一格才能运行否则不能运行 // scanf(%d, arr[i][j]);// } // // } // for (int i 0;i len;i) // { // for (int j 0;j len2;j) // { // printf(%d , arr[i][j]); // } // printf(\n); // } // return 0; //}