C语言回顾之函数与数组


一、什么是函数

任何一个C语言程序都是由一个或者多个程序段(小程序)构成的,每个程序段都有自己的功能,我们一般称这些程序段为“函数”。所以,可以说C语言程序是由函数构成的。
比如你用C语言编写了一个MP3播放器程序,那么它的程序结构如下图所示:


二、函数的定义

1、定义函数的目的

将一个常用的功能封装起来,方便以后调用

2、定义函数的步骤

(1)函数名:函数叫什么名字

(2)函数体:函数是干啥的,里面包含了什么代码

3、格式

(2)固定格式

返回值类型  函数名(形式参数列表)
{
     //函数体
}
(2)举例
定义一个函数,计算两个整数的和
int sum(int a, int b)
{
     return a + b;
}
4、函数调用

(1)sum(10, 11); 引出返回值

(2)当编译器看到有函数的调用会时,就会跳转到定义该函数的地方执行函数,若函数写在main函数之后,则需要在main函数之前进行声明,例如在main函数之前声明:sum(int a,int b);
(3)return 表示从被调函数返回到主调函数继续执行,返回时可附带一个返回值

三、函数的参数

1、形参和实参

形参是说明参数类型,实参是实际有值的参数,例如. 比如你定义一个函数int sum(int a, int b),这里的a和b就是形参,当进行函数调用的时候,sum(1,2),这里的1和2就是实参。

2、形参个数和实参一致

3、参数的传递是值传递

4、参数名不能跟函数内的局部变量同名

5、函数可以没有参数 例如

double PI()
{
  return 3.14
}


四、函数的返回值

1、返回值就是指函数经过运行之后计算出来并可以返回给调用者的结果

2、void:没有返回值

3、return:返回标识符,表示从被调函数返回到主调函数继续执行,返回时可附带一个返回值

4、void函数可以省略return

5、可以多次使用return

6、return后面不能有其他语句

4.函数的弱语法

1、如果没有写返回值类型,默认是int

2、如果写了返回值,可以不返回

3、调用一个没有定义过的函数

五、定义函数的步骤

1、明确函数作用,起一个有意义的函数名称

2、明确函数的参数和返回值
3、举例:

求两个整数的和

int sum(int num1,int num2)
{
  return num1+num2;
}

打印一条横线

void printfLine(int n)
{
     printf("-");
}

打印N条横线
void printfNLine(int n)
{
  for(int i=0;i<n;i++)
  {
     printf("-\n");
  }
}

六、函数注意

1、不能嵌套定义函数

2、死循环调用:自己调用自己

3、不能重复定义、可以重复声明


七、函数的补充
1、main函数
返回值:0,正常退出;1,异常退出
2、printf函数
(1)需要包含头文件stdio.h #include  <stdio.h>
(2)返回值:字符串的长度

八、函数的声明
1、函数的声明作用:声明和定义,类似于身份证和人的关系,编译买机票、链接登机
2、只有函数声明、没有定义,编译警告、链接报错

九、h文件和.c文件的分工

1、单文件的坏处
(1)一个文件的内容太多,不利于阅读、调试
(2)多人修改同一个文件出问题
(3)公司里面是团队合作

2、将sum函数抽取到另一个.c文件中
(1)先直接调用sum函数,编译警告、链接main.c错误
(2)#include “sum.c” , 编译链接main.c,运行成功
(3)如果avr.c中使用sum.c,编译链接main.c,运行程序

3、在其他文件中声明sum函数
int sum(int,int); 
编译链接main.c 失败
编译链接sum.c 失败
编译链接main.c  sum.c,运行成功
avr.c利用一样的方法

4、将int sum(int,int)抽取到另外一个文件中
(1)不抽取声明的坏处:增加新的函数了
(2)抽取到.c文件中?开发工具会将所有的.c进行编译链接
(3)抽取到.h文件中

5、抽取步骤总结
(1).c文件写函数的定义
(2).h文件写函数的声明
(3)要想用函数,包含声明了该函数的.h文件

十、#include
1、#include的作用
纯粹是文件拷贝
2、#include <stdio.h>
stdio.h中声明了C语言函数的声明
include < >是直接在在系统提供的头文件中进行调用 而include “ ”是在先当前目录下进行搜索,如果没有再搜索系统提供的头文件


十一、数组的基本概念

1、什么是数组
数组,从字面上看,就是一组数据的意思,没错,数组就是用来存储一组数据的
2. 数组的特点
(1)只能存放一种类型的数据,比如int类型的数组、float类型的数组
(2)里面存放的数据称为“元素”

十二、数组的定义
1. 定义
(1)声明数组的类型
(2)声明数组的元素个数(需要多少存储空间)
2、格式
元素类型 数组名[元素个数];
比如:int ages[3];
3、简单使用
(1)简单初始化:int ages[5] = {19, 19, 20, 21, 25};
(2)元素有顺序之分,每个元素都有一个唯一的下标(索引),从0开始
(3)数组元素的访问:a[i]
4、初始化
(1)初始化方式
int a[3] = {10, 9, 6};
int a[3] = {10,9};
int a[] = {11, 7, 6};
int a[4] = {[1]=11,[0] = 7};
(2)常见错误
int a[];
int[4] a;
int a[b];
a = {10, 11};
a[4] = {10,9,8,5}; 
5、内存分析
(1)数组存储空间的大小是由它的类型与数据决定的
(2)存储空间的划分(内存的分配是从高地址到低地址进行的,但一个数组内部元素又是从低到高进行的)
(3)数组名的作用,查看元素地址
(3)数组越界的注意
6、其他使用
(1)数组作为函数参数(sizeof注意)
(2)数组元素作为函数参数
(3)遍历数组元素
(4)两种方式遍历(while循环和for循环)
(5)遍历元素值和元素地址
(6)字符数组的使用
7. 习题
(1)提示输入5个学生的成绩,算出平均分、最高分、最低分,然后输出
#include <stdio.h>
// 学生的个数
#define kCount 5

int main()
{
    // 1.定义一个数组保存5个学生的分数
    // 初始化一下,默认都是-1分,只要默认值不是0~100都行
    int scores[kCount] = {-1, -1, -1, -1, -1};
    
    // 2.定义变量保存总分、最高分(默认是0分)、最低分(默认是100分)
    int sum = 0, max = 0, min = 100;
    
    // 3.提示输入
    for (int i = 0; i<kCount; i++)
    {
        // 3.1 如果学生的成绩不在0~100内,就重新提示输入
        while (scores[i]<0 || scores[i]>100)
        {
            // 3.1.1 提示输入
            printf("请输入第%d个学生的成绩(0~100):\n", i + 1);
            
            // 3.1.2 接收输入
            scanf("%d", &scores[i]);
        }
        
        // 3.2 累加成绩
        sum += scores[i];
        
        // 3.3 判断最高分
        if (scores[i] > max)
        {
            max = scores[i];
        }
        
        // 3.4 判断最低分
        if (scores[i] < min)
        {
            min = scores[i];
        }
    }
    
    // 4.输出结果
    printf("平均分是%d,最高分是%d,最低分是%d\n", sum/kCount, max, min);
}

(2)设计一个函数:int arrayMax(int a[], int count),找出数组元素的最大值
#include <stdio.h>
//设计一个函数:int arrayMax(int a[], int count),找出数组元素的最大值
int arrayMax(int a[], int count)
{
    int max = 0;
    for (int i = 0; i<count; i++) {
        if (max<a[i]) {
            max = a[i];
        }
    }
    return max;
}
int main()
{
    int array[7] = {1,2,3,4,5,6,7};
    int num = arrayMax(array, 7);
    printf("%d",num);

    return 0;
}



(4)设计一个函数:int arraySum(int a[], int n),求一维数组a前n个数的和
#include <stdio.h>
int arraySum(int a[], int n)
{
    int num=0;      // num一定要初始化
    for (int i = 0; i<n; i++) {
        
        num+=a[i];
        
    }
    return num;
}

int main()
{
    int a[] = {1,2,3};
    int sum = arraySum(a, 2);
    printf("%d",sum);
    return 0;
}



(4)设计一个函数:将一维整型数组中的元素逆序存放。比如本来是1,3,4,2,逆序存放就变成了:2,4,3,1
/*
设计一个函数:将一维整型数组中的元素逆序存放。比如本来是1,3,4,2,逆序存放就变成了:2,4,3,1
*/
#include <stdio.h>
void reverse(int array[], int len);

int main()
{
    int ages[4] = {1, 3, 4, 2};
    
    reverse(ages, 4);
    
    for (int i = 0; i<4; i++)
    {
        printf("%d\n", ages[i]);
    }
    
    return 0;
}

// 第一个参数是数组,第二个参数是数组长度
// 不需要返回值
// 因为改变了形参数组就相当于修改了外面的实参数组
void reverse(int array[], int len)
{
    // 思路:以数组中间为轴,交换左右对称元素的值
    // 比如array[0] array[1] array[2] array[3] array[4] array[5]
    // 交换array[0]和array[5]的值
    // 交换array[1]和array[4]的值
    // 交换array[2]和array[3]的值
    
    // 左边元素的下标(默认是最左边)
    int left = 0;
    // 右边元素的下标(默认是最右边)
    int right = len - 1;
    
    // 如果左边元素的下标 < 右边元素的下标
    while (left < right)
    {
        // 利用中间变量交换两个元素的值
        int temp = array[left];
        array[left] = array[right];
        array[right] = temp;
        
        // 交换一次后,左边元素下标增加,右边元素下标减小
        
        left++;
        right--;
    }
}




十二、 二维数组
1、什么是二维数组
一个数组能表示一个班人的年龄,如果想表示很多班呢?
什么是二维数组?int ages[3][10]; 三个班,每个班10个人
相当于3行10列,相当于装着3个一维数组
二维数组就是一个特殊的一维数组:它的元素是一维数组。例如int a[2][3]可以看作由一维数组a[0]和一维数组a[1]组成,这两个一维数组都包含了3个int类型的元素

2、初始化
int a[3][4] = {1,2,3,4,5,6};
int a[3][4] = {{},{},{}};
数组元素简单访问:int a[][5] = {3,21,31,2,32,1};
注意错误:int a[3][4];a[3] = {};这样赋值是错的
3、使用注意
     a[3][4] 表示有3行4列
     a、a[0] 、&a[0]均为该数组的首地址,即为该数组的地址
     *a、a、a[0] 和&a[0][0]是等价的,表示表示第0行元素的首地址
     a+1 表示第一行元素的首地址,a[1]、*(a+1)、&a[1][0]与其是等值的
     a[0]+1表示的是a[0]的1号元素首地址,即a[i]+j表示二位数组第i行第j列元素的地址


4. 遍历
(1)遍历所有的元素
//遍历二维数组的元素
    int a[2][2] = {{1,2},{3,4}};
    for (int i = 0; i<2; i++) {
        for (int j = 0; j<2; j++) {
            printf("%d,",a[i][j]);
        }
    }

(2)遍历地址
//遍历二维数组元素的地址
    int a[2][2] = {{1,2},{3,4}};
    for (int i = 0; i<2; i++) {
        for (int j = 0; j<2; j++) {
            printf("%p,",&a[i][j]);
        }
    }

十三、字符串
1、什么是字符串
简单的字符串”itcast”
一个’i’是一个字符
很多个字符组合在一起就是字符串了
2、字符串的初始化
char a[] = “123”;  和 char a [] = {‘1’,’2’,’3’};的区别,前者能当字符串用,后者只能当字符数组用
“123”其实是由’1’、’2’、’3’、’\0’组成
“123”的存储分布,从低位到高位
字符串的输出”%s”,’\0’是不会输出的
3、\0的作用
作为一个字符串的结束符
4、常用字符串处理函数
strlen(注意中文)
可以用来计算字符的个数,一个中文字符算一个
5
、习题
编写一个函数char_contains(char str[],char c),如果字符串str中包含字符c则返回数值1,否则返回数值0
BOOL char_contains(char str[],char c)
{
    for (int i=0;str[i]!='\0' ; i++) {
        if (str[i]==c) {
            return 1;
        }
    }
    return 0;
}
int main()
{

    char str[] = "adfas";
    printf("%d",char_contains(str,'b'));
    return 0;
}

十四、 字符串数组
1.使用场合
 一维字符数组中存放一个字符串,比如一个名字char name[20] = "cx"
如果要存储多个字符串,比如一个班所有学生的名字,则需要二维字符数组,char names[15][20]可以存放15个学生的姓名(假设姓名不超过20字符)
如果要存储两个班的学生姓名,那么可以用三维字符数组char names[2][15][20]
2.初始化
char names[2][10] = { {'J','a','y','\0'}, {'J','i','m','\0'} };  
char names2[2][10] = { {"Jay"}, {"Jim"} };  
char names3[2][10] = { "Jay", "Jim" };


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值