1.形参中不存在数组的概念,即便中括号约定数组的大小,也无效

  1. 案例:
    #include void printArr(int arr[10])//传递进来一个数组,形参用数组的形式来写{int i;for(i=0; i<10; i++){printf("%d ", arr[i]);}putchar('\n');printf("printArr: arr的大小是:%d\n", sizeof(arr));}int main(int argc, char const *argv[]){int arr[10] = {1,2,3,4,5,6,7,8,9,10};printf("main: arr的大小是:%d\n", sizeof(arr));printArr(arr);//数组名作为函数的实际参数return 0;}
  2. 运行结果:
  3. 问:我们可以在函数中对数组元素进行调用,但为什么在函数中,数组的长度不是40反而是8呢?
  4. 原因:数组名字作为实参传递给函数时,传递的只是一个地址,是数组的首地址。地址就是指针的概念,不同的编译器,地址所占用的内存大小不同,在GCC编译器中,地址占8个字节(用%p输出能看见16位16进制数);在VS编译器中,地址占4个字节(用%p输出能看见8位16进制数)。

2.做数组相关操作时,除了传递数组首地址之外,还应该传递数组的长度

  1. 原因:主调函数中数组的长度如果发生改变,那么还得去修改函数里面的逻辑,不方便
  2. 改进思路:用sizeof关键字计算数组的长度,然后作为实参传递给函数。
    #include void printArr(int arr[], int len){int i;for(i=0; i<len; i++){printf("%d ", arr[i]);}putchar('\n');printf("printArr: arr的大小是:%d\n", sizeof(arr));}int main(int argc, char const *argv[]){int arr[10] = {1,2,3,4,5,6,7,8,9,10};int len;len = sizeof(arr) / sizeof(arr[0]);printf("main: arr的大小是:%d\n", sizeof(arr));printArr(arr, len);return 0;}

3.数组作为函数参数的两种写法

  1. 基本原理:数组的内存中是一块连续的存储区域,数组名代表了数组的首地址。
  2. 写法一:数组的名字作为实参
    printArr(arr, len);
  3. 写法二:数组的首地址作为实参
    printArr(&arr[0], len);

​​​​​​​

4.数组名作为函数参数与普通变量名作为函数参数的区别

不同点:

  1. 数组名作为实参:传递的是一个地址,数组名是数组的首地址。函数中数组元素的改变会直接影响主调函数中数组元素的值。
  2. 普通变量名作为实参:传递的是一个数据。函数中变量的改变不会影响主调函数中变量的值。

相同点:二者都满足:

  1. 满足:函数调用的四个过程(无论是传递地址还是传递数值,都是值传递,只不过一个是地址的数值,一个是数据的数值)。
  2. 满足:形参和实参不是同一个变量,它们只是数值相等,但他们的内存地址不同。虽然说我们传递数组名时,传递的是它的首地址,形参也接收的是首地址,但是注意首地址也是一个数据,那么这两个地址数据又保存在哪里呢?答案是两个不同的内存地址中。
  3. 满足:形参和实参的作用范围不同

5.习题

代码心得:

  1. 我们以后会经常听到API:英文是,application Interface,意思是应用程序接口,是函数封装的意思。
  2. 可以将数组的初始化写进一个api,可以将遍历打印数组也写进一个api,等等。

习题1:有两个班级的同学,分别是10个人和5个人,分别求这两个班的平均分。

  1. 思路:
    f1. 封装初始化数组的API:void initArry(int arry[], int len); 形参分别是数组首地址,数组长度f1.1 for循环,表示数组下标的循环变量i从0开始,<len 时,将纳入循环f1.1.1 输入成绩f2. 封装打印数组的API:void printArry(int arry[], int len); 形参分别是数组首地址,数组长度f2.1 打印总人数f2.2 for循环,表示数组下标的循环变量i从0开始,<len 时,将纳入循环f2.2.1 打印数组元素值f2.3 换行f3. 封装获取数组平均数的API:float getAverage(int arry[], int len); 形参分别是数组首地址,数组长度f3.1 for循环,表示数组下标的循环变量i从0开始,<len 时,将纳入循环f3.1.1 修改用于求和的循环变量sum的值: sum += arry[i];f3.2 计算平均值:aver = sum / len;f3.3 返回平均值aver1. 定义两个数组,分别代表两个班级2. 用sizeof运算符获取数组的长度3. 用API1. 对两个数组初始化4. 用API2. 打印两个数组5. 用API3. 获取两个班级平均数6. 打印平均数
  2. 代码:
    #include  void initArry(int arry[], int len);void printArry(int arry[], int len);float getAverage(int arry[], int len);int main(int argc, char const *argv[]){int classOne[5];int classTwo[10];float averageOfClassOne;float averageOfClassTwo;int lenOfClassOne = sizeof(classOne)/sizeof(classOne[0]);int lenOfClassTwo = sizeof(classTwo)/sizeof(classTwo[0]);/* 初始化数组 */initArry(classOne, lenOfClassOne);initArry(classTwo, lenOfClassTwo);/* 打印数组 */printArry(classOne, lenOfClassOne);printArry(classTwo, lenOfClassTwo);/* 计算平均分 */averageOfClassOne = getAverage(classOne, lenOfClassOne);averageOfClassTwo = getAverage(classTwo, lenOfClassTwo);printf("一般的平均分:%f\n", averageOfClassOne);printf("二班的平均分:%f\n", averageOfClassTwo); return 0;}void initArry(int arry[], int len){int i;for(i=0; i<len; i++){printf("请输入第%d个学生的成绩:\n", i+1);scanf("%d", &arry[i]);}}void printArry(int arry[], int len){int i;printf("总人数%d个\n", len);for(i=0; i<len; i++){printf("%d ", arry[i]);}puts("\n done \n");}float getAverage(int arry[], int len){float aver = 0.0; //平均分float sum = 0;//总分int i;for(i=0; i<len; i++){sum = sum + arry[i];}aver = sum / len;return aver;}

习题2:封装冒泡排序法的函数

  1. 思路:回顾冒泡排序法
  2. 代码:
    void bubbleSort_SmallToLarge(int arr[], int len){int i, j; //分别是外、内层循环变量int temp; //用于交换的临时变量for(i=0; i<len-1; i++){for(j=0; j arr[j+1]){//arr[j]是摆擂者,arr[j+1]是被挑战者,大的浮上去,所以用>判断temp = arr[j];arr[j] = arr[j+1];arr[j+1] = temp;}}}}

习题3:封装选择排序法的函数

  1. 思路:回顾选择排序法
  2. 代码:
    void selectionSort_SmallToLarge(int arr[], int len){int i, j; //分别是外、内层循环变量int temp; //用于交换的临时变量int sword;//尚方宝剑for (i=0; i<len-1; i++){sword = i;//暂时把尚方宝剑交给第i个人for (j=i+1; j<len; j++){//j每次都从i+1开始,因为一轮开始时尚方宝剑在第i个人手中if (arr[sword] < arr[j]){ //尚方宝剑在arr[sword]位置,让arr[j]轮流去挑战,大的夺走swordsword = j;}}if (sword != i){//判断尚方宝剑是否还在第i个人手中temp = arr[i];arr[i] = arr[sword];arr[sword] = temp;}}}