C语言入门基础知识(持续更新中)
1.1 什么是C语言
1.1 .1计算机语言
------语言是人与人之间交流媒介
计算机语言的发展历程------机器语言->汇编语言->高级语言
(1. 面向过程:C 2. 面向对象:C++,JAVA,python,PHP······)
1.1.2 机器语言
机器语言:计算机是一种电子设备,计算机处理的数字信号是 0和1去记录相应信息,利用数字语言0和1来表示计算机能够识别的通断和断电两种状态。那么计算机的语言成为机器语言,自然也就是0和1序列,这种 0 和1 序列被称为二进制代码。
1.1.3 汇编语言
汇编语言:汇编的出现简化程序员的工作,在汇编语言中,用便于记忆的方法定义程序指令(用助记符代替机器码的指令集)。
1.1.4 高级语言
高级语言:既然机器语言和汇编语言都是计算机可以理解的语言,可用于完全控制计算机的行为,那为什么还会设计出并使用高级语言呢?因为机器语言和汇编语言都是低级语言,是面向于机器,于具体的计算机相关,学习器来非常困难,编程效率低,可读性,可操作,可维护性差。C语言作为面向过程的计算机编程语言,与C++,Java等面向对象的语言有所不同,其编译器主要有Clang、GCC、WIN-TC、MSVC、Turbo C等。
1.2. C语言的特点
C语言作为面向过程的计算机编程语言,属于高级语言范畴,它既有高级语言的特点,又有汇编语言特点。设计目标是提供一种能以简易方式编译、处理低级储存器的编程语言。它可以作为工作系统设计语言,编写系统应用程序,也可以作为应用程序设计语言,编写不依赖计算硬件的应用程序,代码精简,十分灵活。
它把高级语言的基本结构和语与低级语言的实用性相结合,C语言可以像汇编语言一样对位,字节和地址进行操作,而这三者是计算机最基本的工作单元。
1.2.1 C语言程序的特点
1. C语言简洁,紧凑,使用方便,灵活;
2. 符丰富,共有34种;
3. 数据结构丰富;
4. 可移植性好(相对于汇编);
5. 生成目标代码质量高,程序执行效率高,C语言允许直接访问物理地址,能进行位(bit)操作,能实现汇编语言的大部分功能,可以直接对硬件进行操作。
1.2.2 C语言程序的注意点
1. 一个C语言源程序可以由一个或多个源文件组成;
2. 每一个源文件可由一个或多个函数组成;
3. 一个源程序不论由多少个文件组成,都有一个且只能有一个main函数,即主函数。
(程序由主函数开始运行,主函数结束程序);
4. 源程序种可以有预处理命令(include 命令仅为其中一种),预处理命令通常应放在源文件或源程序的最前面(程序的编译从主文件的第一行开始,主函数结束编译结束);
5. 每一个说明,每一个语句都必须以分号结尾。有例外:预处理命令,函数头和花括号“}”之后不能加分号(一个分号代表了一个语句结束);
6. 标识符,关键字之间必须至少加一个空格以示间隔;
1.2.3 C语言程序的编程风格*
1. 一个说明或一个语句占一行。
2. 用{ }括起来的部分,通常表示了程序某一层次结构,{ }一般与该结构的第一个字母对齐,并单独占一行。
3. 低一层次的语句或说明可以高一层次的语句或说明缩进若干个后书写,以便看起来更加的清晰,增加程序的可读性。
总结:在编程应该遵循这个规定,以养成良好编程习惯和编程风格,好的代码风格要求缩进整齐,每一个语句一行,适当留空行。
1.3. C语言程序开发
1.3.1 第一个C语言程序
C语言项目由头文件.h和源文件.c组成,我们写的一般是源文件;
说明:1)#include <stdio.h>表示头文件包含,标准的输入输出头文件;
以#开头的行,通常是我们要调用系统库函数时,需要包含相应的头文件,预编译的意思是:以#include <stdio.h>为例,在程序编译之前将stdio.h文件的内容添加到程序(原样拷贝);
2)main-->主函数,每一个C语言程序有且仅有一个main函数,main前面的int表示该函数的返回值类型。主函数后面跟着{ },C语言的函数后面都要有一对{ };
3)在main函数的{ }内部的代码时函数体部分,其中printf 是一个函数调用,调用stdio 里面的库函数,用于输出数据;
4)return 0:表示程序的返回值,对应main前面的int。
注意:C语言是严格区分大小写的
#include "stdio.h"
/ *
# ------预编译符号
inlcude ------预编译命令
" " < > ------<>代表是系统提供的库 " "代表自定义的库
stdio ------标准输入输出库
.h ------头文件
main ------主函数
( ) ------包括的形参
printf ------输出函数,并在屏幕上打印对应内容
* /
代码示例:
#include "stdio.h"
int main()
{
printf("hello world!!")
return 0;
}
注释:
1. // 和 /*......*/(不支持嵌套,注意/*和*/的正确配对)
2. 注释的作用和好处:主要用于给读者提供说明,提高程序的可读性,C语言编译器会忽略掉所有的注释,将其视为空白。但我们要养成编码的同时随手写注释的好习惯。特别是程序比较复杂的,代码量比较大的程序,就越有必要写注释,方便他人理解代码,方便自己总结,检查与回顾。
1.3.2 C语言的开发过程
1. 编辑:使用文本编译工具录入程序代码,生成源程序*.c ,*.cpp;
2. 编译:语法分析差错,翻译生成目标程序 *.obj;
3. 链接:与其他目标程序或库链接装配,生成可以执行程序*.exe;
4. 执行:运行最终的可执行文件。
2.1 C语言进制数表示
2.1.1 二进制数、八进制数和十六进制数的表示
- 二进制:二进制由0和1两个数字组成,使用时必须以0b或0B开头,例如0b110;
- 八进制:八进制由0~7八个数字组成,使用时必须以0开头,例如015(十进制中的13)
- 十六进制:十六进制由数字0~9组成、字母A~F或a~f组成,使用时必须以0x或0X组成(不区分大小写)例如0X2A(十进制的42)
- 进制进位方式 逢十进一
2.1.2 进制之间的换算
十进制转二进制: 除二取余 余数反转
十进制转八进制: 除八取余 余数反转
十进制转十六进制: 除十六取余 余数取反
2.1.3 八四二一码
进制转换一般模式:任意进制先转换为二进制再去转其他进制;
举例:十六进制转十进制或八进制
0XEA--------11101010----128+64+32+0+8+0+2+0=234---- 16^1*14+16^0*10 = 234
0352---------011 101 010----128+64+32+0+8+0+2+0=234---8^2*3+8^1*5+8^0*2=234
2.2 C语言的数据类型
2.2.1 数据类型分类及取值范围
类型 | 类型说明符 | 字节数 | 取值数 |
字符型 | char | 1 | 0~256 |
基本整形 | int | 4 | -2147483648~2147483647 |
短整型 | short int | 2 | -32768~32767 |
长整型 | long int | 4 | -2147483648~2147483647 |
无符号整型 | unsigned int | 4 | 0~4294967295 |
无符号短整型 | unsigned short | 2 | 0~65535 |
无符号长整型 | unsigned long | 4 | 0~4294967295 |
单精度实型 | float | 4 | 3/4E-38~3/4E+38 |
双精度实型 | double | 8 | 1/7E-308~1/7E+308 |
注意:数据类型前可以加unsigned,则变成无符号数,不加是默认是signed(有符号数)
Char ---- 1个字节 ---- 8位 ---- 1111 1111---- 0~255 ---- 256个数表示范围应该是 0~2^8-1
Int ----- 4个字节 ---- 32 ---- 0~2^32-1
注意:在32位编译器下 int 为32位,在16位编译器下 int 为16位
2.2.3 数据类型转换
C语言的类型有很多,当不同数据类型之间进行混合运算的时候,可能会引起混乱,为此产生了一种转换机制(一种数据转换成另一种数据类型),若参加运算的数据类型不同时,就要先将其转换为相同类型,最后再运算;
转换的规则有两种:
1. 自动转换规则
float在进行运算的时候无论是否由double类型都会自行转换成double进行运算;
Char和short运算时都会自动转换位int运算;
2. 强制转换规则
将一种数据类型强制转换成另外一种数据类型;
C语言强转类型一般格式为:(类型说明符)表达式;
例子:(float)a 或者是(int)(x+y)
强制转换注意内容:
- 浮点型转整型的时候:将浮点型(单双精度)转换为整型的时候,会舍弃掉小数点后面的数字,只保留整数部分;
- 单双精度相互转换:double型转float型时,先截取双精度的前7位有效数字,然后赋值单精度类型的变量;
- 字符型和整型的相互转换: 将整形赋给字符型时,只将低8位的赋给字符,高位的全部舍弃;
- 无符号与有符号的相互转换:若占据同样长度存储单元的有符号,无符号整数相互转换时,是原样赋值,内部的存储方式不变,但外部值可能发生改变。
2.3 C语言基础
2.3.1标识符
C语言程序中需我们命名的对象,如:变量,符号常量,函数名,自定义数据类型名等;
C语言规定标识符只能由字母,数字和下划线组成;
- 其中第一个字符必须是字母或下划线;
- 不能是关键字;
- 严格区分大小写;
以下表示符是合法的: a ,x3,BOKK,_7,abc6.......
2.3.2 关键字
1.C语言预先定义的一些标识符,被C语言赋予特定含义的小写单词;见如下:
auto | break | case | char | const | continue | default | do |
double | else | enum | extern | float | for | goto | if |
int | long | register | return | short | signed | sizeof | static |
struct | switch | typedef | union | unsigned | void | volatile | while |
2.关键字及含义内容如下:
关键字 | 含义 | 关键字 | 含义 |
auto | 声明自动变量 | int | 声明整型变量或函数 |
break | 跳出当前循环 | long | 声明长整型变量或函数返回值类型 |
case | 开关语句分支 | register | 声明寄存器变量 |
char | 声明字符型变量或函数返回值类型 | return | 子程序返回语句(可带参数,也可不带参数) |
const | 声明只读变量 | short | 声明短整型变量或函数 |
continue | 结束当前循环,开始下一轮循环 | signed | 声明有符号类型变量或函数 |
default | 开关语句中的“默认”分支 | sizeof | 计算数据类型或变量长度(即所占字节数) |
do | 循环语句的循环体 | static | 声明静态变量 |
double | 声明双精度浮点型变量或函数返回值类型 | struct | 声明结构体类型 |
else | 条件语句否定分支(与 if 连用) | switch | 用于开关语句 |
enum | 声明枚举类型 | typedef | 用以给数据类型取别名 |
extern | 声明变量或函数是在其它文件或本文件的其他位置定义 | unsigned | 声明无符号类型变量或函数 |
float | 声明浮点型变量或函数返回值类型 | union | 声明共用体类型 |
for | 一种循环语句 | void | 声明函数无返回值或无参数,声明无类型指针 |
goto | 无条件跳转语句 | volatile | 说明变量在程序执行中可被隐含地改变 |
if | 条件语句 | while | 循环语句的循环条件 |
2.4 常量与变量
2.4.1变量
在程序的运行中,其值可以改变的量叫变量。
1. 变量在内存中占据一定的存储单元,用存放该变量的值,变量由变量类型,变量名,变量值组成:
(1)变量类型表示该变量用来存储什么类型的数据;
(2)变量名用来区分不同的变量;
(3)在变量的存储单元中存放的值为变量值;
2. 定义变量:变量类型 变量名 变量值
数据类型 变量名1 = 初始值1....数据类型 变量名N = 初始值N
举例:如--------int a = 10;
#include "stdio.h"
int main()
{
变量类型 变量名 变量值
int a = 10;
return 0;
}
3. 在使用一个变量之前,应注意----先定义 后使用
原因:定义变量是为变量指定数据类型,这个是编译就能在内存中分配相应存储单元。
4. 变量命名
- (1)只能由字母、数字、下划线组成,不能以数字开头;
- (2)变量名严格区分大小写;
- (3)变量名不能使用关键字;
- 5. 变量分类
- 局部变量:位于大括号内部定义的变量
- 全局变量:位于大括号外部定义的变量
-
#include "stdio.h" int a = 1010;//全局变量 { int b = 2020;//局部变量 return 0; }
注意:(1)局部变量可以和全局变量同名;
(2)当局部变量和全局变量同名时,局部变量优先使用,就实现了变量覆盖;
(3)局部变量的作用域是变量你所在的局部范围,全局变量的作用域是整个工程,不同源文件都可以使用。
6. 变量的作用域和生命周期
(1)作用域——一段程序代码中所用到的名字并不总是有效的/可用的,而限定这个名字的可用性代码范围就是这个名字的作用域;
- 局部变量的作用域是变量所在的局部范围
- 全局变量的作用域是整个工程
(2)生命周期——指变量的创建到变量的销毁之间的一个时间段;
- 局部变量的生命周期是:进入作用域生命周期开始,出作用域生命周期结束
- 全局变量的生命周期是:整个程序的生命周期
2.4.2 指针变量
内存地址:在内存中以字节为单位存储数据,每一个字节有相对应值,这个值就是内存地址;
变量地址:变量在内存空间中所属的位置;
变量的内容:内存空间中存放的内容----也就是变量的值;
#include "stdio.h"
int main()
{
int dat = 30;
//变量存储时数值,但是它本身也有内存空间 内存空间=地址
//指针变量本质是地址 但是是变量,存储的是其他地址
int *sp = &dat;
printf("%d\r\n",dat);
printf("%d\r\n",&dat);
printf("%d\r\n",sp);
printf("%d\r\n",&sp);
}
2.4.3 常量
1. 定义:在程序运行过程中,其值不能被改变的量称之为常量。
常量同样对应着内存中的一块存储区域,通过常量名可以对其区域进行访问,和变量唯一不同之处在于便能改变常量的值。
2. 常量的前缀:(通常用来表示常量的进制:0表示八进制,0x十六进制)
常量后缀:(通常用来表示常量的类型:u表示无符号,l表示长类型,f表示浮点型,d表示double)
3. C语言中常量的分类:
- (1)字面常量
(2)const 修饰的常变量
(3)#define定义的标识符常量
(4)枚举常量
#include "stdio.h"
int main
{
3.14; //字面变量
"abc";//字面变量
const int a=10; //在C语言中,const修饰的是a,本质是变量,但是不能被修改,有常量的属性
a = 20;
printf("%d\n",a); //20 const 修饰的常变量
return 0;
}
#define max 10 //#define 定义的标识符常量
int main()
{
printf("%d\n",max);
return 0;
}
enum Color //枚举常量
{
RED; //枚举常量
GREEN;
BLUE;
}
int main()
{
printf("%d\n",RED);
printf("%d\n",GREEN);
printf("%d\n",BLUE);
return 0;
}
2.4.4 符号常量
定义:通常一个符号表示一个常量数据,常量名通常采用大写,符号常量可以用两种形式来定义
常量的定义格式:
1)宏:#define P1 3.14159265 这个语法是预编译指令语法,没有结尾
2)Const: Const float 3.14159265 这个语法是标准C语言常变量语法
2.4.5 直接常量
1. 整型变量:十进制整数常量------0~9-----逢十进一,整型变量默认是int类型;
2. 八进制整型变量:通常以0开头----0~7---逢八进一;
3. 十六进制整型变量:以0x开头----0~9,a~f---逢十六进一;
4. 浮点型变量:小数形式,是以十进制形式存在 比如:0.0 0.5 5.1等,浮点型默认是double类型的;
5. 指数形势(由十进制+阶码标志‘e’或‘E’),例如:1.2E3 =1.2*10^3;
6. 字符常量:字符常量使用一对单引号括起来的一个字符,例如‘a’,‘10’,‘+’;
2.5 字符串+转义字符+注释
2.5.1 字符串
1. 定义:由双引号引起来的一串字符称为字符串字面值,简称字符串,"abc"
注:字符串的结束标志是一个\0的转义字符,在计算字符串长度时,不作为字符串内容;
#inclde "stdio.h"
int main()
{
char arr1[]="abcd";
char arr2[]={'a','b','c','d','\0'};
printf("%s\n",arr1);
printf("%s\n",arr2);
printf("%d\n",strlen(arr1)); //字符串长度为4
//string length,求字符串长度的函数 头文件string.h
retuurn 0;
}
2.5.2 转义字符
定义:转变原来字符的意思,转义字符:用‘\’开头的字符序列(\n:换行)
字符串常量:用一对双引号括起来的字符序列,并且以‘\0’为结束标志,在内存中占的字节数为字符+1
转义字符 | 释义 |
\? | 在书写连续多个问号时使用,防止他们被解析成三字母词 |
\' | 用于表示字符常量' |
\" | 用于表示一个字符串内的双引号 |
\\ | 用于表示一个反斜杠,防止他被解释为一个转移序列符 |
\a | 警告字符,蜂鸣 |
\b | 退格符 |
\f | 进纸符 |
\n | 换行 |
\r | 回车 |
\t | 水平制表符 |
\v | 垂直制表符 |
\ddd | ddd表示1~3位的八进制数所代表的字符----例如\101------A |
\xdd | dd表示1~2位的十六进制数所代表的字符---例如\x42-----B |
//%d ——打印整型
//%c——打印字符
//%s——打印字符串,例如printf("%s\n","abcdef")
//%f——打印float类型的数据
//%lf——打印double类型的数据
2.5.3 注释
代码中有不需要的代码可以直接删除,也可以注释掉(加//);
代码中有些代码比较难懂,可加文字注释;
/* C语言的注释风格
int a = 10;
int b = 20;
*/
C++的注释风格
// int a = 10;
// int b = 20;
2.6 运算符与表达式
1. 运算符-------就是指具有运算意义的符号--- + - * /等;
2. 表达式-------指编译器能够读懂的计算机语句,由运算符和操作数按一定语法规则结合而成。
3. 按操作数的个数可以把运算符细分:
- 单目运算符(++,--)
- 双目运算符(+,-,*,/)
- 三目运算符(?:运算符)
通常又被分为:算术运算符,逻辑运算符,关系运算符,位运算符,条件运算,赋值运算符,逗号运算,sizeof运算符及其其他运算符。
2.6.1 算数运算符
1. 算术运算符有:加+ 减- 乘* 除/ 取余% 正负号(+ -) 自增(++) 自减(--);
2. 其中前面五个的运算符的结合性是从左到右 ,负号则相反从右到左。
注意:
- 在除法操作的时候,如果被除数和除数都为整型,那么结果一定是整型,舍去小数部分。在取余的操作时,只能用于整型数据;
- ++和--运算符:它们是单目运算符,结合性为从右到左边;
前缀----(++a,--a)表示先将a加上或减去1之后再赋值给左值;
后缀----(a++ , a--)表示先赋值给左值,a再加上或减去1;
2.6.2 逻辑运算符
1. 逻辑运算符有:逻辑与(&&) 逻辑或(| |) 逻辑非(!)
2. !是单目运算符,结合方向从右到左,&&和||为双目运算符,结合方向从左到右。逻辑运算符要求起操作数为布尔值: true 1 false 0
注意:由&&和||运算符组成的逻辑表达式中,C规定只能够确定整个表达式值所需要的最少数目的子表示进行计算,也就是说,当计算出一个子表示式的值后便可以确定整个逻辑表示式的值时,后面的子表达式就可以不需要在进行计算了,这种表达式也称之为短路表达式;
2.6.3 位运算符
存储单元内数据是由 0 和 1 组成,可以通过位运算符改变内存中某单元的某一值;
- 逻辑运算符:&(按位与),|(按位或),^ (按位异或),~(按位取反)左移<< 右移>>
- 按位与:&(有0出0,全1出1)0011&1111 = 0011
- 按位或:|(有1出1,全0出0)0011|1111 = 1111
- 按位异或:^(相同为0,不同为1)0011^1111 = 1100
- 按位取反:~ ~0011 = 1100
- 左移:<< 高位溢出丢弃,低位不足补0:0111001<<2 = 1100100
- 右移: >> 正数:高位补0,低位溢出舍去:0111001>>4 = 0000011 负数:高位补1,低位溢出舍去:11111111>>4 = 11111111
2.6.4 关系运算符(比较运算符)
1. 分类:大于(>) 小于(<) 小于等于(<=) 大于等于(>=) 判断等于(==) 不等于(!=)
2. 结合性:从左到右 ,主要用于程序中的分支判断并在变量和零值得比较应用最广泛
(1)整型变量是否为0:if(x==0)
(2)浮点型变量是否为0:if((x>=-0.0000001) &&(x<=0.0000001))
(3)布尔型得变量是否为0:if(x)
(4)指针类型得变量是否为0:if(x == NULL)
(5)字符类型得变量是否为0: if(x == ‘\0’)
2.6.5 运算符的优先级和结合性
(优先级的数字越小,优先级别越高)
类型 | 优先级 | 运算符 | 含义 | 结合方向 |
初等运算符 | 1 | () [] -> . | 圆括号 下标运算符 指向结构体成员运算符 结构体成员运算符 | 从左到右 |
单目运算符 | 2 | ! ~ ++ -- - (类型) * & sizeof | 逻辑非运算符 按位取反运算符 自增运算符 自减运算符 负号运算符 类型转换运算符 指针运算符 取地址运算符 长度运算符 | 从右到左 |
算术运算符 | 3 4 | * / % + - | 乘法运算符 除法运算符 求余运算符 加法运算符 减法运算符 | 从左到右 |
移位运算符 | 5 | << >> | 左移运算符 右移运算符 | 从左到右 |
关系运算符 | 6 7 | < <= > >= == != | 小于运算符 小于等于运算符 大于运算符 大于等于运算符 等于运算符 不等于运算符 | 从左到右 |
逻辑运算符 | 8 9 10 11 12 | & ^ | && || | 按位与运算符 按位异或运算符 按位或运算符 逻辑与运算符 逻辑或运算符 | 从左到右 |
条件运算符 | 13 | ?: | 条件运算符 | 从右到左 |
赋值运算符 | 14 | =、+=、-=、*=、/=、%=、>>=、<<=、&=、^=、|= | 赋值运算符 | 从右到左 |
逗号运算符 | 15 | , | 逗号运算符 | 从左到右 |
总结:
- 操作数越多的运算符优先级相对低一点:单目—-双目(不包含赋值运算符)---三目—赋值—逗号;
- 双目运算符个数最多,算术运算符---移位运算符---关系运算符---位运算符---逻辑运算符;
- 位运算符:~ & ^ |
- 逻辑运算符:! && ||
- 所有的赋值运算符都具有相同的优先级
3.1 C语言程序结构
九条语句:用来进行程序之间的逻辑设计;
选择:1.if - else 2.switch case default
循环:1.for 2.while 3.do.....while
跳转:1.goto 2.break 3.continue 4.return
3.2 选择结构基本语句
3.2.1 条件判断语句
(1)if语句:单条件判断语句
定义:当满足条件语句时执行{}内的执行语句,否则不执行{}内语句;
if(条件表达式)
{ //条件满足时
要执行的语句;
}
(2) if…else…语句:条件分支语句
定义:当满足条件语句是(条件语句结果非0)执行{ }内执行语句1,否则执行else 后的执行语句2;
if(条件表达式)
{ //条件满足时
要执行的语句;
}
else
{ //条件不满足时
要执行的语句;
}
(3)if…else if…else…语句:多条件分支语句
定义:当不满足条件1时,继续判断下一个条件语句,直到满足条件语句时,则执行当前{}内执行语句1,如果前面所有的条件都不满足时,则执行最后的else中的语句;
if(条件表达式1)
{ //满足条件表达式1
要执行的语句;
}
else if(条件表达式2)
{ //满足条件表达式2
要执行的语句;
}
else if(条件表达式3)
{ //满足条件表达式3
要执行的语句;
}
···
else
{ //所以条件都不满足时
要执行的语句;
}
(4)switch语句:开关语句,一般配合case关键字使用
-
定义:通过表达式得出数值,若得出的数值与下面case后得值对应,则执行相应得语句,若没有相应得数值则会执行最后的default后面的语句;
-
switch(表达式) { case 值1: //如果表达式的值等于1,则执行下面语句1 执行语句1; break; //如果没有break则不会跳出语句回一直往下执行 case 值2: //如果表达式的值等于1,则执行下面语句2 执行语句2; break; ··· case 值n: //如果表达式的值等于n,则执行下面语句n 执行语句n; break; default: //如果表达式中没有相对应的值时则执行语句n后跳出 执行语句n+1; break; //break可省略 }
3.2.2 循环结构基本语句
(1)for语句 -
-
for (表达式1;表达式2;表达式3)
(循环变量赋初值;循环体条件;循环变量增量)
{
执行语句;
}
代码示例:
#include "stdio.h"
int main()
{
int i = 0;
for(i=0;i<10;i++)
{
printf("%d只羊\r\n",i);
}
}
(2)while语句 条件循环语句,当满足循环条件的情况下循环执行
while(条件语句) //循环条件
{
执行语句;
}
代码示例:
#include "stdio.h"
int main()
{ //两种用法皆可
int i = 0; //int i = 10;
while(1) //while(i--)
{
printf("你好!\r\n");
}
}
(3)do while语句
与while循环的区别:do…while会先执行一遍循环体里面的语句,再进行条件判断,也就是说,do…while至少会执行一次循环体中的语句;
do
{
执行语句;
}while(条件语句); //循环条件
代码示例:
#include "stdio.h"
int main()
{
int i = 10;
do
{
printf("你好!\r\n");
}while(1)
} //do···while先执行后判断,while先判断后执行
3.2.3 转移结构基本语句
(1)goto:强制跳转语句(少用)给一个标志位,定义出一个标志;
(2)return:跳出函数语句,用于跳出函数并返回一个值,函数类型是什么就返回什么值;
#include "stdio.h"
int fun(void)
{
return 10;
}
int main()
{
printf("%d\r\n",fun());
} //运算结果为10
(3) break:中断语句,一般用于循环结构中,作用是终止循环,当执行到break语句时,会立即退出循环;
#include "stdio.h"
int main()
{
int i;
while(1)
{
printf("不想上学...\n");
while(1)
{
printf("玩物丧志中...\r\n");
for(i=0;i<100;i++);
break;//跳出一个循环 只能跳出当前的循环
}
printf("必须上学!!!\n");
break;//跳出一个循环
}
printf("GG\n");
}
(4)continue:跳过本次循环语句,一般用于循环结构中,作用是跳过当次循环,当循环语句执行到continue时,不会继续向下执行,会跳过当次循环,直接执行下一次循环;
#include "stdio.h"
int main()
{
int i = 10;
while(i--)
{
if(i%2 == 1)
{
continue; //跳过本次循环
printf("hello!\r\n");
}
printf("%d\r\n",i);
}
} //运算结果为 8 6 4 2 0
3.2.4. 复合语句
定义:将多个语句用大括号括起来组成一个复合语句;
{
int a = 10;
a++;
int b = a + 1;
}
4.1 数组的定义
数组就是构造类型的一种,它是由一组数目固定、类型相同的若干个数据构成的有序集合,在内存中连续存放。数组中的每一个数据称为一个元素,通过数组名和下标来访问;
定义:一组相同类型元素的集合
int arr[10] = {1,2,3,4,5,6,7,8,9,10}; //定义一个整型数组,最多放十个元素
4.2 一维数组
4.2.1 数组的定义
(1)定义:一维数组也称向量,用以组织具有一维顺序关系的一组同类型数据;
(2)定义格式:类型 数组名 [常量表达式];
(3)类型可以是int, float, char以及后面的指针、结构体、共用体等。例: int age[10];
(4)初始化:类型 数组名 [常量表达式] = {值1,值2,值3...值n};
例: int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
4.2.2 数组的使用
使用:一维数组中元素的引用方式:数组名 [下标]
4.2.3 数组的下标
下标的值表示元素在数组中的位置,C语言规定任何数组的下标都是从0开始的
例:int age[5];表示age有5个元素,这5个元素分别为age[0]、age[1]、age[2]、age[3]、age[4]
注意:除了在定义数组时可以用初始化列表为数组整体赋值之外,其他地方不能对数组整体赋值。
4.2.4 数组的赋值
对数组的所有元素赋初值时,可在定义数组时不指定元素个数,例:int a[5] = {3, 0, 4, 9, 6}; 等价于int a[] = {3, 0, 4, 9, 6};系统在编译程序时,根据初值的个数确定元素的个数,并为它分配相应大小的空间。如果没有为数组变量赋初值,则在定义数组变量的时候不能省略数组的大小。例: int a[];这是错误的
对数组的部分元素赋初值,常量表达式的个数小于数组中元素的个数,未指定的数组元素自动变为0。例: int a[5] = {3, 4, 5}; 等价于 int a[5] = {3, 4, 5, 0, 0}。
5.1 函数概述及分类
5.1.1 函数的概述
语句是构成程序的最基本单位,函数也是由语句构成的,从程序设计的角度上说,函数(一系列语句)常被当成一个整体来看,这就降低了程序的复杂度。
引入函数的目的:方便结构化、模块化编程;解决代码的重复使用问题。一个C程序可由一个主函数和若干个函数构成。
5.1.2 函数的分类
(1)函数从用户使用的角度可以分为:标准函数和用户自定义函数
- 标准函数:即库函数。由系统提供的设计好的函数,用户可以直接调用;
例如:printf()—scanf()—fabs()—sqrt()—gets()—getchar()等等都是库函数;
- 用户自定义函数:用户自己根据需要定义的函数;
(2)函数从形式上又可以分为:无参函数和有参函数
(3)实现一个函数步骤:函数的定义、函数的声明、函数的调用;
5.2 函数的定义
1. 函数定义由函数头和函数体两部分组成,其基本形式为:
返回类型 函数名(形参列表) //函数头
{ //函数开始
变量说明部分和执行部分 //函数体
} //函数结束
注意:执行部分必须在变量说明部分之后。
(1)返回类型:用来说明函数返回值的类型,如果没有返回值,则应声明为void。缺省情况下函数的返回值类型是int;
- 有返回值类型的时候必须有返回值,有返回值的时候必定有返回值类型。
(2)函数名:必须是合法的标识符,与变量的命名规则相同,不能与其他的函数名或变量重名;
- 函数名第一个单词首字母小写,第二单词开始首字母都大写。
(3)形参列表:0个或多个变量,用于向函数传送数值或从函数带回数值(传入参数和传出参数),每个参数都应采取“类型 变量名”形式,参数列表中的参数称为形式参数,简称形参;
- 编译器并不会在函数定义时为这些参数分配内存空间,只有在函数调用时,向函数传递了实参后,这些参数才称为程序实体。如果没有形参,此函数叫无参函数,可以写一个void。
(4)函数体:由一对{ }括起来的语句,主要包括两部分;
- 变量说明部分通常用来定义在函数体中使用的变量、数组等;
- 执行部分是函数功能的实现。程序执行到函数体中的return语句返回,在函数体中可以有多个return语句,但函数只能有一个出口,只执行一条返回语句,返回语句的基本形式为:return 表达式; 表达式的类型应当与函数头中指定的返回类型一致,否则,编译器会根据函数头中指定的返回类型对表达式进行强制类型转换。
5.2.1 return返回
(1)作用:
- 撤销函数调用时为参数和变量分配的栈内存空间;
- 向调用函数(上级)返回最多一个值(表达式的值);
- 将程序流程从当前函数返回上级函数。
(2)当函数的返回类型是void时,表明函数不向上级函数返回任何值,这时可以用一个空的“return;”语句,将程序流程返回,撤销函数调用时为参数和变量分配的栈内存空间,空的“return;”语句位于函数末尾时,该语句可以省略,用函数体的后花括号实现函数的返回即可。
5.3 函数的声明---作用域
1. 函数声明,也称函数原型。函数声明,用以通知编译器函数的存在,有多少形式参数,参数类型和是否有返回值,返回值类型等等,以获得函数的使用许可。和变量一样,函数在调用之前要“先声明,后使用”。
2. 调用库函数时,需要在程序的开头用#include命令,包含这个库函数所在的头文件。调用用户自定义的函数,而且该函数与主函数在同一个程序中,一般应该在主调函数中对被调函数作声明。
3. 函数声明的基本格式:返回类型 函数名(形参列表);
例: int add(int a, int b); 或 int add(int, int);
4. 当被调函数定义在主调函数之前时,可以省略被调函数的定义。
5.4 函数的调用
1. 函数调用的一般格式:有参的:函数名(实参列表); 无参的:函数名();
如果是无参函数,则没有实参列表。如果有参数,则各实参之间用逗号隔开,并且实参的个数、类型应该与函数的形参个数、类型一致。不一致时会进行实参到形参的强制类型转换。
2. 函数的调用过程:被调函数的所有形参分配内存,在计算实参的值,并一一对应的赋给相应的形参(无参函数不做该步骤);
为函数说明部分中定义的变量分配内存,再依次执行函数的语句。执行到return 表达式;时,计算返回值。
释放在本函数中定义的变量所占用的存储空间(对于static类型的变量,其空间不释放),返回主调函数继续执行。
在前面的学习中大家已经熟悉了main()函数,一个C程序里包含一个主函数(即main函数)和若干个其它函数,main()处于最顶层,其他函数作为其下层模块,main()函数调用其它函数,其它函数之间也可以互相调用。