目录

  • 1 课程导论
    • 1.1 课程整体介绍
      • 1.1.1 所有专业人才培养方案
    • 1.2 为什么学(WHY)
      • 1.2.1 行业需求分析
      • 1.2.2 计算机等级考试大纲
      • 1.2.3 软件水平考试大纲
    • 1.3 课程性质及作用(WHAT&WHERE)
    • 1.4 学什么(WHAT)
      • 1.4.1 程序设计基础_知识图谱
    • 1.5 如何学(HOW)
      • 1.5.1 课程考核
      • 1.5.2 课程学习资源
      • 1.5.3 程序设计基础A_考试大纲
      • 1.5.4 蓝桥杯相关备赛资料
      • 1.5.5 程序设计基础学习资料
  • 2 程序与程序设计语言
    • 2.1 课前挑战
      • 2.1.1 扩展知识学习
        • 2.1.1.1 计算机发展史
        • 2.1.1.2 计算机系统构成
        • 2.1.1.3 计算机应用
        • 2.1.1.4 信息编码与存储
    • 2.2 课程导入(WHERE)
    • 2.3 要点解析(WHAT)
      • 2.3.1 什么是程序
      • 2.3.2 C程序基本结构如何
      • 2.3.3 什么是计算机指令
        • 2.3.3.1 指令与程序
      • 2.3.4 什么是计算机语言
        • 2.3.4.1 程序设计语言
        • 2.3.4.2 C语言概述
    • 2.4 项目实战(HOW)--60秒关机
    • 2.5 项目拓展(HOW)--查看本机IP地址
    • 2.6 实验(训)项目一:C语言编程基础
      • 2.6.1 学长说--第一个程序
      • 2.6.2 拓展练习代码截图
    • 2.7 章节通关测试--程序与程序设计语言
  • 3 问题求解与算法设计
    • 3.1 课前挑战
      • 3.1.1 问题求解与算法设计
      • 3.1.2 程序设计思想
    • 3.2 课程导入(WHERE)
    • 3.3 要点解析(WHAT)
      • 3.3.1 什么是算法
      • 3.3.2 算法有什么特征
      • 3.3.3 算法的描述方式
    • 3.4 项目实战(HOW)--流程图绘制
    • 3.5 项目拓展(HOW)--目标检测算法流程表述
    • 3.6 学长说--矩形面积计算
    • 3.7 章节通关测试-- 问题求解与算法设计
  • 4 标识符;数据类型
    • 4.1 课前挑战
    • 4.2 课程导入(WHERE)
    • 4.3 要点解析(WHAT)
      • 4.3.1 标识符的命名规则
      • 4.3.2 数据类型
    • 4.4 项目实战(HOW)--学习强国平台数据类型分析
    • 4.5 项目拓展(HOW)--GDP;北斗风电场数据类型分析
    • 4.6 学长说--查看数据类型内存空间
    • 4.7 章节通关测试--标识符与数据类型
  • 5 常量、变量
    • 5.1 课前挑战
      • 5.1.1 相关知识提前学--常量
      • 5.1.2 相关知识提前学--变量
    • 5.2 课程导入(WHERE)
    • 5.3 要点解析(WHAT)
      • 5.3.1 什么是变量、什么是常量
      • 5.3.2 如何声明变量及常量
    • 5.4 项目实战(HOW)--报文解密
    • 5.5 项目拓展(HOW)--疫情可视化
    • 5.6 章节通关测试--常量与变量
  • 6 运算符与表达式
    • 6.1 课前挑战
      • 6.1.1 相关知识提前学--运 算 符
      • 6.1.2 相关知识提前学--赋值运算符与赋值表达式
      • 6.1.3 相关知识提前学--自增、自减
      • 6.1.4 相关知识提前学--类型转换
      • 6.1.5 相关知识提前学--位运算
    • 6.2 课程导入(WHERE)
    • 6.3 要点解析(WHAT)
      • 6.3.1 赋值运算符及表达式
      • 6.3.2 算术运算符及表达式
      • 6.3.3 数据类型的转换
    • 6.4 项目实战(HOW)--报文解密
    • 6.5 项目拓展1·(HOW)--报文解密
      • 6.5.1 项目拓展--北斗卫星导航定位原理
    • 6.6 学长说--报文解密
    • 6.7 章节通关测试--运算符与表达式
  • 7 数据输入、输出
    • 7.1 输入、输出函数
      • 7.1.1 课前挑战
      • 7.1.2 课程导入(WHERE)
      • 7.1.3 要点解析(WHAT)
        • 7.1.3.1 输出函数printf
        • 7.1.3.2 输入函数scanf
      • 7.1.4 项目实战(HOW)--工资核算
        • 7.1.4.1 学长说--工资核算
      • 7.1.5 项目拓展(HOW)--北斗卫星导航定位原理
      • 7.1.6 学长说--报文解密2
      • 7.1.7 章节通关测试--输入、输出
    • 7.2 字符、字符串的输入输出函数
      • 7.2.1 课前挑战
      • 7.2.2 课程导入(WHERE)
      • 7.2.3 要点解析(WHAT)
        • 7.2.3.1 字符数据的输入、输出
        • 7.2.3.2 字符串数据的输入、输出
      • 7.2.4 项目实战(HOW)--学习强国登录模块1
      • 7.2.5 项目拓展(HOW)--学习强国用户注册1
      • 7.2.6 章节通关测试--字符、字符串的输入输出
  • 8 顺序结构程序设计
    • 8.1 课前挑战
    • 8.2 课程导入(WHERE)
    • 8.3 要点解析(WHAT)
      • 8.3.1 顺序结构
      • 8.3.2 基本语句
    • 8.4 项目实战(HOW)--工资核算
    • 8.5 项目拓展(HOW)--报文解密实例
    • 8.6 实验(训)项目二:结构化程序设计1--顺序结构
    • 8.7 第一阶段测试:C语言编程基础
  • 9 选择结构程序设计
    • 9.1 关系运算符及逻辑运算符及运算符优先级
      • 9.1.1 课前挑战
      • 9.1.2 课程导入(WHERE)
      • 9.1.3 要点解析(WHAT)
        • 9.1.3.1 关系运算符与关系表达式
        • 9.1.3.2 逻辑运算符与逻辑表达式
        • 9.1.3.3 运算符优先级
      • 9.1.4 项目实战(HOW)--学习强国登录模块1
      • 9.1.5 项目拓展(HOW)--打字练习
      • 9.1.6 选择结构上机实训
      • 9.1.7 章节通关测试--关系运算符及逻辑运算符及运算符优先级
    • 9.2 单分支及双分支结构
      • 9.2.1 课前挑战
        • 9.2.1.1 条件运算符与条件表达式
      • 9.2.2 课程导入(WHERE)
      • 9.2.3 要点解析(WHAT)
      • 9.2.4 项目实战(HOW)--快捷支付程序模拟
      • 9.2.5 项目拓展(HOW)--学习强国登录2;自动驾驶汽车
      • 9.2.6 学长说--软件设计师证书生成程序模拟
      • 9.2.7 学长说--银行卡账户余额支付
      • 9.2.8 章节通关测试--单分支及双分支结构
    • 9.3 多分支结构
      • 9.3.1 课前挑战
      • 9.3.2 课程导入(WHERE)
      • 9.3.3 要点解析(WHAT)
        • 9.3.3.1 if else嵌套
        • 9.3.3.2 switch语句
      • 9.3.4 项目实战(HOW)--普通话等级鉴定
      • 9.3.5 项目拓展(HOW)--了不起我的国
      • 9.3.6 实验(训)项目二:结构化程序设计2--选择结构
      • 9.3.7 学长说--天气预报实现演示1 if else嵌套
      • 9.3.8 学长说--天气预报实现演示;switch语句
      • 9.3.9 学长说--switch恐龙世界
      • 9.3.10 学长说--普通话等级鉴定1--if;else嵌套
      • 9.3.11 学长说--普通话等级鉴定2--switch
      • 9.3.12 章节通关测试--多分支结构
  • 10 循环结构程序设计
    • 10.1 自增/自减运算符与自增/自减表达式
    • 10.2 while&do-while循环
      • 10.2.1 课前挑战
      • 10.2.2 课程导入(WHERE)
      • 10.2.3 要点解析(WHAT)
      • 10.2.4 项目实战(HOW)--音乐喷泉程序模拟
      • 10.2.5 项目拓展(HOW)--KEEP运动迹模拟
      • 10.2.6 学长说--音乐喷泉实例
      • 10.2.7 章节通关测试--while&do-while循环
    • 10.3 for循环
      • 10.3.1 课前挑战
      • 10.3.2 课程导入(WHERE)
      • 10.3.3 要点解析(WHAT)
      • 10.3.4 项目实战(HOW)
      • 10.3.5 项目拓展(HOW)--输出矩阵数据
      • 10.3.6 学长说--慈善募捐
      • 10.3.7 学长说--100~200之间的不能被3整除的数
      • 10.3.8 章节通关测试--for循环
    • 10.4 for循环嵌套
      • 10.4.1 课前挑战
      • 10.4.2 课程导入(WHERE)
      • 10.4.3 要点解析(WHAT)
      • 10.4.4 项目实战(HOW)--慈善募捐
      • 10.4.5 项目拓展(HOW)--矩阵操作
      • 10.4.6 实验(训)项目二:结构化程序设计3--循环结构
      • 10.4.7 学长说--输出以下4×5的矩阵
      • 10.4.8 学长说--打印图形1
      • 10.4.9 学长说--打印图形2
      • 10.4.10 学长说--输出100-200间的素数
      • 10.4.11 学长说--我爱你中国升级版-for循环嵌套
      • 10.4.12 第二阶段测试:结构化程序设计
  • 11 数组
    • 11.1 一维数组
      • 11.1.1 课前挑战
      • 11.1.2 课程导入(WHERE)
      • 11.1.3 要点解析(WHAT)
      • 11.1.4 项目实战(HOW)--成绩统计1
      • 11.1.5 项目拓展(HOW)--斐波拉契数列
      • 11.1.6 学长说--成绩统计1
      • 11.1.7 学长说--斐波拉契数列问题
      • 11.1.8 章节通关测试--一维数组
    • 11.2 二维数组
      • 11.2.1 课前挑战
      • 11.2.2 课程导入(WHERE)
      • 11.2.3 要点解析(WHAT)
      • 11.2.4 项目实战(HOW)-- 成绩统计1
      • 11.2.5 项目拓展(HOW)--图像卷积模拟
      • 11.2.6 学长说--成绩统计二
      • 11.2.7 章节通关测试--二维数组
    • 11.3 字符数组及字符串函数
      • 11.3.1 课前挑战
      • 11.3.2 课程导入(WHERE)
      • 11.3.3 要点解析(WHAT)
      • 11.3.4 项目实战(HOW)--学习强国登录
      • 11.3.5 项目拓展(HOW)
      • 11.3.6 学长说--学习强国的登录模块
      • 11.3.7 第三阶段测试:数组
  • 12 模块化程序设计--函数
    • 12.1 函数的定义、参数、声明
      • 12.1.1 课前挑战
      • 12.1.2 课程导入(WHERE)
      • 12.1.3 要点解析(WHAT)
      • 12.1.4 项目实战(HOW)
      • 12.1.5 项目拓展(HOW)--学习强国用户模块1
      • 12.1.6 学长说--四则混合运算
      • 12.1.7 章节通关测试--函数的定义、参数、声明
    • 12.2 函数的调用、常用库函数调用
      • 12.2.1 课程导入(WHERE)
      • 12.2.2 课前挑战
      • 12.2.3 要点解析(WHAT)
      • 12.2.4 项目实战(HOW)--自助点餐系统
      • 12.2.5 项目拓展(HOW)--学习强国用户模块2
      • 12.2.6 章节通关测试--函数的调用、常用库函数调用
      • 12.2.7 学长说--求自然数的平方根(库函数应用)
      • 12.2.8 学长说--大小写字母转化
      • 12.2.9 学长说--产生随机数序列
    • 12.3 函数的嵌套、递归调用
      • 12.3.1 课前挑战
      • 12.3.2 课程导入(WHERE)
      • 12.3.3 要点解析(WHAT)
      • 12.3.4 项目实战(HOW)--斐波拉契数列问题
      • 12.3.5 项目拓展(HOW)--学生年龄信息处理
      • 12.3.6 学长说--阶乘问题1--函数的嵌套调用
      • 12.3.7 学长说--阶乘问题--递归调用
      • 12.3.8 学长说--斐波拉契数列问题--函数递归调用
      • 12.3.9 章节通关测试--函数的嵌套、递归调用
    • 12.4 内部、外部函数变量的作用域和存储方式及函数应用
      • 12.4.1 课前挑战
      • 12.4.2 课程导入(WHERE)
      • 12.4.3 要点解析(WHAT)
      • 12.4.4 项目实战(HOW)--阶乘问题
      • 12.4.5 学长说--静态局部变量(static局部变量)
      • 12.4.6 学长说--输出1到5的阶乘值
      • 12.4.7 第四阶段测试:模块化程序设计
  • 13 数组与指针、指针变量作函数参数
    • 13.1 课前挑战
    • 13.2 课程导入(WHERE)
    • 13.3 要点解析(WHAT)
      • 13.3.1 指针的概念
      • 13.3.2 ​定义指针变量
      • 13.3.3 ​指针的运算
    • 13.4 项目实战(HOW)--指针的应用
    • 13.5 项目拓展(HOW)--指针的拓展应用
    • 13.6 章节通关测试--数组与指针、指针变量作函数参数
  • 14 结构体与共用体
    • 14.1 课前挑战
    • 14.2 课程导入(WHERE)
    • 14.3 要点解析(WHAT)
      • 14.3.1 结构体概念
      • 14.3.2 定义结构体
      • 14.3.3 声明结构体变量及赋值
    • 14.4 项目实战(HOW)--学生成绩
    • 14.5 项目拓展(HOW)--商品信息管理
    • 14.6 章节通关测试--结构体与共用体
  • 15 结构体指针、链表操作
    • 15.1 课前挑战
    • 15.2 课程导入(WHERE)
    • 15.3 要点解析(WHAT)
    • 15.4 项目实战(HOW)
    • 15.5 项目拓展(HOW)
    • 15.6 章节通关测试--结构体指针、链表操作
  • 16 文件操作
    • 16.1 课前挑战
    • 16.2 课程导入(WHERE)
    • 16.3 要点解析(WHAT)
    • 16.4 项目实战(HOW)
    • 16.5 项目拓展(HOW)
    • 16.6 第五阶段测试:C语言高级编程
  • 17 预编译和宏定义
    • 17.1 预编译概念
    • 17.2 #define命令
    • 17.3 #include命令
    • 17.4 条件编译
    • 17.5 其他指令
字符数组及字符串函数

字符数组及字符串函数

一 、课前知识提前学习

字符数组

用来存放char型数据的数组称为字符数组。字符数组的每一个存储单元存放一个字符(1个字节)。字符数组的定义、初始化和引用的规则和数值型数组规则完全相同。例如:

  char s1[10]; /*定义一个名为sl的一维字符数组,包含10个元素,占据内存10个字节*/

  char s2[3][4]; /*定义一个名为s2的二维字符数组,包含12个元素,也可以将其看作包含了3个一维字符数组*/      


初始化方式有按初值顺序赋值和分行赋值两种。例如:

     char s1[10]={‘h’, ’e’, ‘l’, ‘l’, ‘o’},s2[2][3]={{‘a’, ‘b’, ‘c’}, {‘d’, ‘e’, ‘f’}};

表示将字符逐个赋值给数组中每个元素,未赋初值的元素将初始化为空字符NULL。

当有全部初值时定义字符数组可以省略一维长度。例如:

     char d[][3]={{‘ ’, ‘ ’, ‘*’}, {‘ ’, ‘*’, ‘*’}, {‘*’, ‘*’, ‘*’}};


字符数组的每一个元素都可以单独当作字符变量来引用,例如一个简单图像的输出处理过程。

int i, j;

char d[3][3]={{‘ ’, ‘ ’, ‘*’}, {‘ ’, ‘*’, ‘*’}, {‘*’, ‘*’, ‘*’}};

for(i=0; i<3; i++)

 { 

      for(j=0; j<3; j++)

            printf(“%c”, d[i][j]);

            printf(“\n”); 

}

字符串

字符串为双引号括起来的字符序列,例如:“Hello!”、“C Program”等。

C语言中没有提供字符串数据类型,而是使用字符数组表示并保存字符串。字符串实际上是字符数组的一个特例。由于每个字符串都以空字符('\0')结束,在声明一个存储字符串的字符数组时,必须保证字符数组的长度比字符串的长度至少多一个,用以存储字符串的结束符'\0'。

常用的以字符串作初值进行字符数组初始化的方式为:

char c[] = {“Hello”} ; 或 char c[] = “Hello”; 

编译器将字符串“Hello”中的字符赋值到字符数组c中,然后追加一个'\0',从而使数组c可以作为字符串使用。初始化后,字符数组都包含6个元素,其中最后一个元素为'\0',称为字符串结束标志,其ASCII码值为0。与下面字符数组的初始化方式等价:

char c[] = {‘H’,‘e’,‘l’,‘l’,‘o’,‘\0’ } ; 或 char c[6] = {‘H’,‘e’,‘l’,‘l’,‘o’,‘\0’ } ;

但下面两种定义形式并不等价的:
       char c[]={‘H’,‘e’,‘l’,‘l’,‘o’}; /*字符数组,其数组长度为5*/
       char c[]={“Hello”}; /*字符数组表示的字符串,数组长度为6*/

字符数组初始化的字符串的长度应小于字符数组声明的长度时, 例如:

     char c[10]={“Hello”};    

系统将剩余元素都初始化为空字符(‘\0’)。

考虑一下:如果初始化字符串的长度大于所定义的字符数组长度会怎样?

只能在初始化时将字符数组初始化为字符串,不能在程序执行语句中将字符串赋值给字符数组。例如:

char str[10];

str="hello"; /*错误的赋值语句*/

如果在执行语句中需要将字符串常量赋给字符数组,应使用字符处理函数或用循环语句进行处理。

字符串的输入/输出

字符串的输入/输出可以调用scanf/printf以及gets/puts等函数实现。

(1)单字符的输入/输出

利用scanf或printf可以输入或输出字符数组中的任一字符,也可以利用循环语句完成字符的输入/输出处理(利用结束符'\0'作为循环中止的条件)。例如:

charstr[]="string output";

 int i;

 printf(“%c, %c”, str[0], str[6]); /*输出某指定字符*/

 for(i=0; str[i]!='\0'; i++) 

       printf("%c",str[i]); /*循环控制输出字符串*/


(2)字符串格式化输入/输出

使用printf函数的格式控制符%s可以输出字符串。与%s对应的是字符数组的名称或字符串常量。例如:

charstr[]="string output";

printf("%s", str);

printf函数逐个读取字符串中的字符直到遇到空字符('\0')作为输出结束符为止。如果一个字符串中有多个'\0',则遇到第一个'\0'即认为字符串结束。'\0'本身作为结束符并不会被输出显示。

使用scanf以格式说明符%s输入字符串时,字符数组名不需要附加地址运算符&。scanf函数在字符串读入结束时自动在字符串末尾存储一个'\0'字符。例如:

char str[20];

scanf(“%s” ,str );

若用户输入hello后回车,hello被保存到str[0]至str[4]等数组元素,'\0'被写到str[5]中,其余元素也被填充为'\0'。

由于scanf的输入操作遇到空格中止,无法使用scanf输入一个包含空格的字符串。如上例中,用户输入字符串hello world,保存到str数组里的将只有hello。

(3)gets/puts函数输入/输出

使用puts函数一次可以输出一个字符串。 puts函数的使用方式为:puts(字符数组名); puts函数只有一个参数,即需要显示的字符串,可以是字符数组名或字符串常量。例如:

charstr[]="string output";       

puts(str); /*或puts("string output");*/

若输入有空格的字符串时应使用函数gets。gets函数以回车符作为输入的结束,并存储'\0'。例如:

char str [10];

gets(str); /*可以从键盘输入string input*/


字符串输入/输出过程中需要注意:

(1)不要试图输出一个没有字符串结束符的字符数组。由于字符数组没有结束符'\0',printf和puts会在输出正确结果之后,继续遍历后续的内存单元,直到遇到'\0'为止。导致输出不确定的字符。
      (2)使用scanf或gets输入字符串时,若输入字符的数目大于字符数组的长度,多出的字符则会存放在数组的合法存储空间之外,造成数组越界操作。

常用字符串处理函数

C语言中,常用字符串处理函数原型声明在<string.h>头文件中。#include<string.h>

(1)字符串复制函数

程序执行语句中不能将字符串常量或其它字符数组直接赋值给字符数组。字符串的赋值可以使用strcpy字符串复制函数。

函数调用形式:strcpy(字符数组1, 字符串2)

strcpy()将字符串2的内容复制到字符数组1中,包括结尾的字符串结束符'\0'。字符串2可以是字符串常量或是字符数组变量。例如:

char s1[10],s2[10], s3[]="Hello!";

strcpy(s1, s3); /*s1中的字符串是Hello! */

strcpy(s2, “World”); /*s2中的字符串是World*/

strcpy函数要求字符数组l的长度要大于字符串2的长度,否则将造成数组越界操作。

(2)字符串连接函数

strcat函数可以将两个字符串连接起来,形成一个新的字符串。

函数调用形式:strcat(字符数组1, 字符串2)

strcat()函数的字符串2的内容(可以是字符串常量或是字符数组变量)连接到字符数组1的后面,字符数组1中的结束符被自动删除,形成一个新的字符串。例如:

chars1[30]="The classname is "; 

strcat(s1, “C programming.”); /*s1的字符串是The classname is C programming. */

strcat函数要求字符数组1的长度必须足够大,以便能容纳两个字符数组中的所有值。

(3)字符串比较函数

不能直接比较两个字符数组的名称来决定二者是否相等,使用strcmp函数比较两个字符串的大小,结果为整数值。

函数调用形式:strcmp(字符串1,字符串2);

如果字符串1和字符串2完全相等,函数返回0;如果字符串1大于字符串2,函数返回一个正整数;如果字符串1小于字符串2,函数返回一个负整数。

字符串比较的规则是:将两个字符串从左至右逐个字符按其ASCII码值进行比较,如果所有字符都相等(遇到'\0'),则这两个字符串相等。如果出现了不相等的字符,以第一个不相等字符的ASCII码值大小结果作为字符串比较的返回值。 例如:

char s1[]="CLanguage"; int num;

num=strcmp(“abc”,s1); /*因为‘a’<>‘C’,且‘a’的ASCII值比较大,因此函数返回值>0*/


(4)字符串长度函数

使用strlen函数获取字符串的实际长度,函数返回值不包括结束符。

函数调用形式:strlen(字符串);

例如:

charstr[]="hello";

 printf(“%d”, strlen(str)); /*输出字符串长度为5*/

字符串数组

一个字符串本身是一个一维字符数组,多个字符串则可以定义一个二维字符型数组来保存,数组的每一行都保存一个字符串。例如:

charstr_array[10][20];

str_array数组的左下标(行)决定字符串的个数(10个);数组的右下标(列)说明每个串的最大长度(20个字符,包括'/0'),表示定义一个存放10个字符串的字符串数组的,每个串的最大长度为20个字符。

定义字符串数组时,数组的第二个下标应比实际字符串长度大1,以存放字符串结束标志'\0'。同样,可以对字符串数组进行初始化。 例如:

    char string[][8]={“This”, “is”, “a”, “C”,“Program”}; 


字符串数组的每个字符串所占内存的空间是一致的,应取最大的字符串长度作为二维数组列的大小。当所处理的多个字符串长度差异比较大时,就会浪费内存空间,如表1所示。

表1  二维字符数组的存储举例

字符数组的存储

字符类型的变量在存储时只占用一个字节,字符数组长度就是内存中所占的字节数。 例如:

      char c[6]; 

系统为数组c分配6个字节的内存单元。 

当数组保存字符串时,如果省略了数组长度,则系统所分配的字节数为字符串中字符个数加1,最后一个字节用于存储字符串的结束符‘\0’。 例如:        

      char str[]=“Hello”;                                                             

str数组在内存中的存储形式如图4所示(假设数组的首地址为2C80)。 

 图4 字符串的存储