一、C语言基础

1、程序

程序:解决完成特定功能(任务)的流程步骤

计算机程序:让计算机区实现解决问题的步骤执行

计算机语言:计算机能够识别任务的内容(指令)

机器语言:使用0和1表示指令功能

汇编语言:把机器语言指令用助记符进行表示

高级语言:类似自然语言的编写方式

2、C程序的编写编译

Linux中编写C语言程序。编写工具:vim编辑器:在终端上编写文件内容

2.1、vim操作

vim:打开vim编辑器

vim + 文件名:打开对应文件。文件不存在则创建新文件

1、命令模式(默认):键盘输入任何内容都是命令(进入插入模式:i、a、o)(进入底行模式::)

  • 插入命令

命令

作用

a

在光标所在位置之后插入

A

光标所在行尾插入

i

在光标所在位置之前插入

I

在光标所在行首输入

o

在光标所在行下一行插入(新建一行)

O

在光标所在行上一行插入(新建一行)

  • 定位命令

命令

作用

gg

跳转到第一行开通

GG / ]]

跳转到最后一行开头

nG / :n

跳转到第n行

0 / $

跳转到光标所在行行首 / 行尾

b

跳转到第一个单词的第一个字符

w

跳转到下一个单词的第一个字符

  • 复制粘贴命令

命令

作用

yy

复制光标当前行

nyy

复制从光标开始的n行

p

把复制的n行粘贴到光标下一行(新建一行)

dd

剪切光标当前行

ndd

剪切从光标开始的n行

x

删除光标所在位置的字符

nx

删除光标所在位置后n个字符(包括光标位置)

nX

删除光标所在位置前n个字符(包括光标位置)

dG

删除光标所在行到文件末

u

恢复

2、插入模式:键盘输入都是操作文本内容(回到命令模式:ESC)

3、底行模式:操作编辑器(回到命令模式:ESC)

  • 保存退出命令

命令

作用

:q(a)

退出(所有文件)

:q!(a)

强制退出不保存(所有文件)

:x / :wq(!)(a)

保存且退出(强制)(所有文件)

:w(a)

保存文件(所有文件)

:w 文件名

另存为

  • 行号显示/删除命令

命令

作用

:set nu

显示行号

:set nonu

不显示行号

:n1,n2d

删除n1行到n2行

  • 查找替换命令

命令

作用

/内容

当前光标位置开始查找对应内容(n:继续查找下一个 / N:反向查找)

:%s/old/new

全文将old替换为new

:n1,n2s/old/new(/c)

n1行开始到n2行将old替换为new(询问)

r

替换光标所在位置字符为输入字符

R

从当前光标开始,使输入的内容替换当前行的内容

2.2、编译与执行

编译:把C程序编译为计算机能够识别的指令

  • 命令:gccgcc file2 >>> 编译file2
  • 执行:./可执行文件名
  • 选项:

        -o:输出文件重命名。

3、C语言基础语法---关键字与标识符

3.1、关键字

  • 在规范C语言时,用于表示一定的特殊含义的字符,只要在C程序中使用,就代表一定的操作含义

C语言32个关键字

auto

double

int

struct

break

else

long

switch

case

enum

register

typedef

char

extern

return

union

const

float

short

unsigned

continue

for

signed

void

default

goto

sizeof

volatile

do

if

while

static

C语言程序中,我们定义的名字不能和关键字重名

  • const关键字

表示在定义变量时,使用const关键字进行修饰,表示当前变量不可修改,可以访问。作用类似于常量。

const 数据类型 变量名;

通常情况下const变量要进行初始化。

const修饰指针变量时:

1、指向类型 * const 指针变量名;

表示指针变量不可修改,但是指向地址中的内容可以修改;即指针变量不可改,*指针变量可以修改。

int * const p1;p1 = &a;(×)指针变量本身无法修改;*p1 = 20(√)可以修改*p1;

2、指向类型 const * 指针变量名;/ const 指向类型 * 指针变量名;

表示指针变量可以修改,但是指向地址中的内容不可修改;即*指针变量不可修改。

int const * p2;p2 = &a;(√)指针变量本身可以修改,变为存储另一个地址;*p2 = 20(×)不可以修改*p3;

3、const 指向类型 * const 指针变量名;

表示指针变量不可修改,指向地址中的内容也不可修改。

const int * const p3;p3 = &a;(×)指针变量本身不可修改;*p3 = 20(×)不可以修改*p3;

3.2、标识符

  • 在当前程序中设定的一些字符符号表示,表示一定的意义,代表一个定义的作用(我们自己所定义的含义)
  • 标准标识符:C语言中预先定义的一些标识符,通常用做固定的库函数名或预编译处理中专门的命令。如 scanf、printf、define、include等。C语言允许用户标识符与预定义标识符同名,但这将使这些标识符社区系统规定的愿意。
  • 标识符表示:由字母、数字、下划线表示。且只能以字母或下划线开始。

4、C语言基础语法---数据类型

4.1、进制与数据

4.1.1、进制表示

  • (D)十进制表示:每位数据值范围:09,满10进1。
  • (B/0B)二进制表示:每位数据值范围:0、1,满2进1。
  • (O/0)八进制表示:每位数据值范围:07,满8进1。
  • (H/0x)十六进制表示:每位数据值范围:0~9,10(A)、11(B)、12(C)、13(D)、14(E)、15(F),满16进1。

4.1.2、进制转换

  • 十进制转N进制:除以N倒取余。
  • 小数十进制转二进制:正乘2取整。
  • N进制转十进制:(进制权 * 当前数值)的累加。
  • 二进制转十六(八)进制:四(三)个二进制位为一个十六(八)进制位,高位不够用0补齐。
  • 十六(八)进制转二进制:十六(八)进制一位为二进制四(三)位。

4.1.3、数的存储

  • 计算机中存储数据以二进制存储,但数据中存在正、负之分。

有符号数:把数据中最高位、作为符号位用。0表示正数、1表示负数。

无符号数:数据中,所有位都是数据位,没有符号位。所有无符号数都是正数。

4.1.4、数的编码

计算机中存储数据以 补码 格式存储。

  • 原码:数据的二进制形式,符号位0则为正数、符号位1则为负数。
  • 反码:正数的反码为源码。负数的反码为源码取反(除符号位)。
  • 补码:正数的补码为原码。负数的补码为反码加一。补码的补码为原码。

位:bit,一个单独的0或1二进制 --- 1bit

字节:八位二进制 --- 1Byte, 1B = 8bit

千字节:KByte --- KB

一千个字节 --- 1KB, 1KB = 1000B

4.2、数据类型

在C语言程序中,存在数据,每种数据都有对应的数据类型。C语言是一种静态类型语言。

4.2.1、基本类型

整型(int)

整数存储:转换为二进制,以补码形式存储。

有无符号:

  • 有符号整型(signed,默认)
  • 无符号整型(unsigned)

在计算机中设定的大小:

  • 短整型(short (int)):16位二进制(16bit / 2B)。

无符号:16位(0 ~ 2^16 - 1),32位(0 ~ 2^16 - 1),64位(0 ~ 2^16 - 1)

有符号:16位(-2^15 ~ 2^15 - 1),32位(-2^15 ~ 2^15 - 1),64位(-2^15 ~ 2^15 - 1)

  • 整型(int):32位二进制(4B)。

无符号:16位(0 ~ 2^16 - 1),32位(0 ~ 2^32 - 1),64位(0 ~ 2^32 - 1)

有符号:16位(-215 ~ 2^15 - 1),32位(-2^31 ~ 2^31 - 1),64位(-2^31 ~ 2^31 - 1)

  • 长整型(long (int)):32位系统(32位二进制 / 4B), 64位系统(64位二进制 / 8B)。

无符号:16位(0 ~ 2^32 - 1),32位(0 ~ 2^32 - 1),64位(0 ~ 2^64 - 1)

有符号:16位(-2^31 ~ 2^31 - 1),32位(-2^31 ~ 2^31 - 1),64位(-2^63 ~ 2^63 - 1)

为了强制编译器把常量作为长整数时,只需在后边加一个字母L(l)。

  • 超长整型(long long (int))(C99标准):64位二进制(8B)。

无符号:64位(0 ~ 2^64 - 1)

有符号:64位(-2^63 ~ 2^63 - 1)

以LL或ll结尾的整数常量是long long int类型。

定义方式:符号关键字 + 尺寸关键字

浮点型(实型)

以二进制补码形式存储:数据部分 + 指数部分

符号位 + 阶码(指数幂) + 尾数(数据值)

  • 单精度实型(float):32位二进制,占4B,精度>>6位可能准确,7位不一定准确

符号位(1位) + 阶码(8位) + 尾数(23位)为了表明只需要单精度,可以在常量的末尾处加上字母F或f。如57.0F。

  • 双精度实型(double):64位二进制,占8B,精度>>15位可能准确,16位不一定准确

符号位(1位) + 阶码(11位) + 尾数(52位)

若为了以long double存储,可以在常量的末尾处加上字母L或l。如57.0L。

  • 扩展精度浮点数(long double):80位或128位

判断小数相等:0.000001> 小数1 - 小数2 > -0.000001

字符型(char)

对于字符型数据,在计算机中存储,依旧使用二进制0和1表示。

在C语言中,使用ASCII码来表示(整数)----8位(8bit),1B

表示方法:用单引号包括

字符类型可以当做整数进行操作。

数组(字符串)类型

数组:由多个数据组成一个数据集合,在集合中存在多个数据内容。

1、一维数组
  • 定义:

类型 数组名[数组长度];

类型:每个数据的类型。

数组名:整个数据集合的名字。

数组长度:数据集合中的数据个数;数组长度应该为常量。

占用内存空间:类型 * 数组长度。

以连续的内存空间创建数组,每个数字元素是相邻的。

  • 数组的访问

为了存取特定的数组元素,可以在写数组名的同时在后边加上一个用方括号围绕的整数值(称这是对数组取下标或索引)。

格式:数组名[ 下标值 ];

下标值是数组元素在数组中的位置,也叫索引值;下标值为整型。

下标值取值范围:0 ~ 数组长度 - 1。

注意:如果下标 >= 长度,叫越界,不能使用。

  • 数组的初始化

在定义一维数组时,可以对数组进行初始化,对数组进行初始化就是对数组的元素进行初始化。

使用一个 {},在花括号中添加要对数组元素初始化的值。

格式:

类型 数组名[ 元素个数 ] = {值1,值2,... ...};

完全初始化:

类型 数组名[ 元素个数 ] = {值1,值2,... ... == 元素个数};

对数组中每个元素都进行初始化赋值,会按照值的顺序依次对数组元素进行初始化。

部分初始化:

类型 数组名[ 元素个数 ] = {值1,值2,... ... < 元素个数};

按照顺序依次初始化数组中前几个值,未初始化的值会有编译器初始化为0;

指定初始化:

类型 数组名[ 元素个数 ] = { [下标值] = 值1,[下标值] = 值2,... ...

在进行初始化时,由于会编写元素值,可以使用值的个数来表示元素个数,在定义的位置元素个数可以不写。

int main()

{

int arr1[] = {1, 2, 3, 4, 5};//元素个数为5个

int arr2[10] = {1, 2, 3, 4, 5};//元素个数为10个

int arr3[] = {[0] = 1, [4] = 2, [2] = 3};//初始化最大下标为4,所以元素个数为5个 int n = 6;

int a[n];//c99允许,c89不允许;数组大小为6,不会根据n的变化而变化

int a = 10;

return 0;

}
2、二维数组

二维数组是一维数组的集合,集合中的数组元素是一维数组。

  • 定义:

数据类型 数组名[ 常量表达式1 ][ 常量表达式2 ];

数据类型:一维数组的元素数据类型。

常量表达式1:二维数组的元素个数(有几个一维数组)。

常量表达式2:在二维数组中的一维数组的元素个数。

  • 二维数组的存储

二维数组中的元素在内存中是按行顺序存放的,系统为它们分配连续的内存空间,即先放第一行的元素,再放第二行的元素,以此类推。

  • 二位数组的访问

数组名[ 二维数组下标 ]:二维数组中的某个一维数组。

数组名[ 二维数组下标 ][ 一维数组下标 ]:一维数组中对应的数据值。

  • 二维数组的初始化

全部初始化:

数据类型 数组名[ 常量表达式1 ][ 常量表达式2 ] = {值1,值2,值3,... ...};

把二维数组从第一个开始,依次进行初始化;

数据类型 数组名[ 常量表达式1 ][ 常量表达式2 ] = { {值1,值2,... ...},{值3,值4,... ...},... ... };

每个 { } 中初始化一个一维数组

部分初始化:

数据类型 数组名[ 常量表达式1 ][ 常量表达式2 ] ={ {值1,值2,... ... < 常量表达式2},{值3,值4,... ... < 常量表达式2},... ... };

对于二维数组初始化时,可以不指定一维数组的个数,即常量表达式1个数,但常量表达式2的个数必须指定。

即:数据类型 数组名[ ][ 常量表达式2 ] = {初始化};

4.2.2、构造类型

由于基本数据类型不能满足需要,需要把多个的数据类型进行组合,共同表示新的复合数据,形成新的类型。构造新的数据类型的方式就叫做构造类型。

结构体(struct)

使用多种数据类型作为成员,进行组合,构成新的类型,就叫做结构体。

  • 声明:结构体的类型表示

struct 结构体名

{

类型1 成员1;

类型2 成员2;

... ...

};

在程序中添加一种新的类型,不占用内存空间,只是说明在程序中有一种新类型。

  • 定义结构体变量

数据类型 变量名;

数据类型:struct 结构体名

  • 结构体的访问

结构体变量名.成员名;

共用体类型(union)

使用多种数据类型作为成员,进行组合,但是使用同一段空间进行存储(多个成员共用一个空间),构成的新的类型,就叫做共用体(联合体)。

使用共用体的问题:同一时刻只能存储一个成员。

所占存储空间为占用最大空间的成员的空间。

  • 声明共用体类型:

union 共用体名

{

类型1 成员1;

类型2 成员2;

... ...

};

共用体用法与结构体相同。

枚举类型(enum)

在定义一种新类型时,这个类型能够取值的范围是确定的,通过这个定义的新类型把能够取值的范围一一列举出来,这种类型就叫做枚举。

声明枚举类型:

enum 枚举名

{

成员1,

成员2,

成员3,

... ...

};

枚举类型中,每个成员代表能够取的一个值。

声明类型时,如果成员没有赋值,成员就等于上一个成员的值+1;如果成员1没有赋值,则为0;

  • 定义枚举变量:

enum 枚举名 变量名;

使用:变量名 = 成员;

4.2.3、指针类型

内存地址:在内存中,对于每一个字节都分配了一个唯一的编号,用于区别不同的位置。每个字节都有唯一的地址。用来和内存中的其他字节相区别。

指针:在内存空间(定义变量)中申请空间用来存储地址,就叫做指针,也叫指针变量。

指针变量的定义:数据类型 *指针变量名

数据类型:储存哪种数据类型的地址,就指向哪种类型,因此要存储那种数据类型的地址,就定义哪种数据类型。

指针变量的使用:指针变量 = 地址(&变量名)(要求地址的空间能够使用,&取地址符)

指针所指向空间数据的访问:*指针名

4.2.4、空类型

void:空类型,表示没有数据类型。

void不能定义变量。

4.3、常量与变量

常量

含义:在整个程序中都不会进行改变的数据。

变量

含义:在整个程序中可以进行变化的数据,在内存中存储数据后,空间中的数据值可以进行改变。

先定义变量才能使用。

  • 变量定义:存储类型 数据类型 变量名

存储类型

  • auto:默认类型

(栈区,由系统进行管理),可以省略。

  • static:静态存储类型

static修饰局部变量:

延长生命周期为整个程序(程序结束变量的生命周期结束),但作用域不变,只能在定义的作用域中使用。

当多次定义static的1局部变量时,只会定义第一次,其余的跳过定义。

static修饰全局变量:

设置为静态变量,只能在本文件内使用这个变量,其它文件无法使用。

未初始化变量,将初始化为0。

  • register:寄存器类型

存储到CPU中(没存入,通常等同于auto)

  • extern:外部类型

变量名

使用标识符表示变量名。

变量初始化

在定义变量时,为变量赋初始值。

5、输入与输出

5.1、输出打印

1、printf()

由C语言标准所设计的输出功能,只要使用printf就可以实现输出打印。(终端)

头文件:#include

格式:printf(“要打印的内容”);

格式化输出

格式:printf("格式化字符", 输出列表);

格式化字符:作用就是占位表示要打印数据值,以%表示。

数据列表:格式化字符要打印的数据

  • 格式化字符

格式字符

功能说明

d

以带符号的十进制形式输出整数(正数不显示+)

u

以无符号的十进制形式输出整数

hd 或 ld 或 lld

分别以短整型、长整型、超长整型输出

o

以八进制无符号形式输出整数

x 或 X

以十六进制无符号形式输出整数。x表示十六进制的a-f小写,X表示十六进制的A-F的大写

f 或 lf

以定点十进制小数形式输出浮点数 / 双精度

E 或 e

以指数形式输出十进制浮点数

G 或 g

根据数值自动采用f或e方式输出。区别在于会自动省去尾随的0或小数点默认精度为6

c

以字符形式输出,只输出一个字符

s

以字符串形式输出

p

输出指针的值或变量的地址

  • 占位符精度:

整数:"%[打印宽度]d"

浮点数:“%[打印宽度] . [打印精度]f”

  • 控制标志

字符

功能说明

-(负号)

输出内容左对齐

+(正号)

在正值之前显示加号,在负值之前显示减号

空格

在位使用+标志打印的正值之前打印空格

#

对于八进制数前面添加0;对于十六进制数前面添加0x或0X;若使用的是g或G,则尾随的0不被消除

0(零)

在前面用0填充空格

  • 转义符

在输出中,如果要输出某些特殊字符,在字符编码上没有对应的字符表示,在C语言中,设计转义字符:把普通字符转义为特殊字符,特殊字符转义为普通字符。

转义字符:\(也是续行符:下一行继续写本行内容)

字符

功能说明

ASCII

字符

功能说明

ASCII

\a

响铃(BEL)

007

\\

代表一个反斜杠字符\

011

\b

退格(BS),将当前位置移到前一列

008

\'

代表一个单引号(撇号)字符

092

\f

换页(FF),将当前位置移到下一页

012

\"

代表一个双引号

039

\n

换行(LF),将当前位置移动到下一行开头

010

\?

代表一个问号

034

\r

回车(CR),将当前位置移动到本行开头

013

\0

空字符(NULL)

063

\t

水平制表符(HT)(跳到下一个TAB位置)

009

\ddd

1到3位八进制数所代表的任意字符

000

\v

垂直制表符(VT)

011

\xhh

十六进制所代表的任意字符

三位八进制

2、puts()

功能:输出应该字符。

3、putchar()

功能:输出字符串,输出完成自动换行。

5.2、输入-存储

1、scanf()

输入功能,从键盘输入数据给变量。使用scanf需包含头文件#include

格式:scanf("格式化字符1,格式化字符2",输入列表);

格式化字符:格式化字符位置匹配的内容输入到变量中。

例:scanf("%d", &a);

输入列表:列表要输入的变量。

输入失败返回 0 ,成功返回 1;

注意:如果是连续两个数值格式化字符,在键盘输入时,需要隔开,通过空格回车。

处理输入函数留下的垃圾:1、用getchar(); 2、scanf("%*c%c", &ch);

scanf("%[^\n]", &ch); // 检测到回车停止输入,通常用于连续输入字符串。

2、gets()

功能:从键盘输入字符串,以回车结束输入。输入长度应小于数组长度。

3、getchar()

功能:从键盘读取一个字符。

返回值:

正常输入,则返回读取的代码值;

异常输入或结束键盘输入,则返回 -1 / EOF(ctrl d)。

6、运算符

只要是使用运算符进行运算时,都会有结果。

6.1、算数运算符与赋值运算符

6.1.1、算术运算符

+:加、-:减、*:乘、/:除、%:取余

进行运算时,如果是同种类型数据进行运算,则结果为对应类型。

隐式类型转换

在进行各种运算操作,如果是不同的数据类型,会把不同的数据类型转换为相同的数据类型,然后再进行运算。(原则:精度低往精度高的类型转换)

强制类型转换

把数据的值取出,然后指定转换为某种类型,原数据不变。格式:(要转换的类型)数据

优先级

(乘、除、取余) 高于 (加、减) >>> 同级的至左向右。

6.1.2、赋值运算符

赋值运算符表达格式:变量 = 操作数;

赋值运算结果为所赋的值。

6.2、关系运算符

  • :大于、>=:大于等于、==恒等于、!=:不等于

关系运算符是进行比较运算,判断关系是否成立(比较左右两边的表达式是否满足关系),成立为真(值:1),不成立为假(值:0)

注意:在进行运算时,如果有连续的多个运算符,单一运算符之后得到结果再与下一个运算符进行运算。

优先级:(>、>=、>> 关系运算符低于算术运算符

6.3、逻辑运算符

连接两个表达式,根据表达式的真假进行组合得到新的结果,结果也为真或假。

  • &&(与)

有假则假,全真为真。

  • ||(或)

有真则真,全假为假。

  • !(非)

取反(是真则假,是假则真)。

优先级:! 高于 (&&、||)

6.4、位运算符

位运算对数据中对应的二进制位进行操作。(不会涉及到符号位的说法)

  • &(按位与)

有0则0,全1为1。

  • |(按位或)

有1则1,全0为0。

  • ^(按位异或)

相同为0,相异为1。

  • ~(按位取反)

有1则0,有0则1.

  • >>(按位左移)

数据值<<移动位数将一个数据所有二进制位向左移动若干位数,高位部分移出,低位部分补零。

  • >>(按位右移)

数据值>>移动位数将一个数据所有二进制位向右移动若干位数,高位部分原先为1则补1(原先为0则补0),低位部分舍去。

6.5、复合运算符

  • 复合运算符:可以使用=(赋值运算符)和其他的运算符(算术运算符、位运算符)结合使用

(+=、-=、*=、/=、%=)、(|=、&=、^=)

表达方式:变量 += 表达式 >>> 变量 = 变量 + 表达式

6.6、其他运算符

6.6.1、自增自减运算符

++、--

  • 变量++(--):先取变量值再自加(减)一。
  • ++(--)变量:先变量值加(减)一,再运算。

6.6.2、条件运算符(三元运算符)

  • 条件表达式:表达式1 ?表达式2 :表达式3(表达式1为真,执行表达式2,把表达式2的结果作为整个条件表达式的结果;否则执行表达式3,把表达式3的结果作为整个条件表达式的结果)

6.6.3、逗号运算符

  • 表达方式:表达式1,表达式2,……,表达式n

依次运算每个表达式,并将最后一个表达式的结果作为整个逗号运算符的结果。

优先级:所有优先级中最低。

6.6.4、sizeof运算符

  • sizeof(数值/类型):计算数据对应类型的大小,以字节表示。

sizeof()运算符的运算结果为长整型。

6.7、运算符优先级

优先级

运算符

名称或含义

使用形式

1

[]

数组下标

数组名[常量表达式]

()

圆括号

(表达式) / 函数名(形参表)

.

成员选择(对象)

对象.成员名

->

成员选择(指针)

对象指针->成员名

2

-

负号运算符

-表达式

~

按位取反运算符

~表达式

++

自增运算符

变量名 / 变量名

--

自减运算符

--变量名 / 变量名--

*

取值运算符

*指针变量

&

取地址运算符

&变量名

逻辑非运算符

!表达式

(类型)

强制类型转换

(数据类型)表达式

sizeof

长度运算符

sizeof(表达式)

3

/

表达式 / 表达式

*

表达式 * 表达式

%

余数(取模)

整型表达式 % 整型表达式

4

+

表达式 + 表达式

-

表达式 - 表达式

5

左移

变量

>>

右移

变量 >> 表达式

6

>

大于

表达式 >表达式

>=

大于等于

表达式 >= 表达式

小于

表达式 < 表达式

小于等于

表达式

7

==

等于

表达式 == 表达式

!=

不等于

表达式 != 表达式

8

&

按位与

表达式 & 表达式

^

按位异或

表达式 ^ 表达式

|

按位或

表达式 | 表达式

9

&&

逻辑与

表达式 && 表达式

||

逻辑或

表达式 || 表达式

10

?:

条件运算符

表达式1 ? 表达式2 : 表达式3

11

=

赋值运算符

变量 = 表达式

/=

除后赋值

变量 /= 表达式

*=

乘后赋值

变量 *= 表达式

%=

取模后赋值

变量 %= 表达式

+=

加后赋值

变量 += 表达式

-=

减后赋值

变量 -= 表达式

左移后赋值

变量 >>= 表达式

>>=

右移后赋值

变量 >>= 表达式

&=

按位与后赋值

变量 &= 表达式

^=

按位异或后赋值

变量 ^= 表达式

|=

按位或后赋值

变量 |= 表达式

12

,

逗号运算符

表达式1, 表达式2,……,表达式n

7、选择结构

根据实际的情况条件,选择性执行或不执行某些功能。

7.1、if...else选择结构

7.1.1、单分支选择结构

根据条件,如果满足条件,则执行对应的功能操作代码,执行完后,继续往下执行;否则就跳过对应功能代码继续往下执行。

  • 表达形式:

if(条件表达式)

{

语句块;

} ---- {}满足if范围的语句块,如果语句块只有一条,{}可省略。

条件表达式:只计算表达式的结果为 真(非0) 或 假(0),如果满足条件,则执行语句块。

7.1.2、双分支选择结构

满足条件表达式,执行一段语句功能内容,不满足则执行另一段功能内容;之后继续往下执行。

  • 表达形式:

if(条件表达式)

{

语句块1;

}else{

语句块2;

}

7.1.3、多分支选择结构

多种情况选择执行一种,判断第一种是否满足,满足则执行,不满足则判断下一种是否满足,满足则执行,不满足继续判断。

  • 表达形式:

if(条件表达式)

{

语句块1;

}else if{

语句块2;

}

... ...

else{

语句块n;

}

7.2、switch...case选择结构

switch选择结构,根据表达式从多种情况中进行选择,选择情况进行执行对应的语句块。

  • 表达形式:

switch(表达式) >>> 比较switch中表达式 是否 等于case的常量表达式,如果相等,则执行相应语句块。

{

case 常量表达式1:语句块1;break; >>> break:表示结束当前switch;如果没有,则会一直执行下去,直到switch结束。

case 常量表达式2:语句块2;break;

case 常量表达式n:语句块n;break;

default:默认语句块段n+1;(break;) >>> 表示switch中表达式 与 case中常量表达式 都不满足,则执行default中语句块。

}

注意:表达式和常量表达式结果为整型。

8、循环结构

重复多次执行某个功能。

8.1、while循环

表达式为真,则执行一次循环体语句,再次判断表达式是否为真,为真则再次执行,直到表达式为假就跳出循环。

  • 表达形式:

while(表达式)

{

循环体语句; ---- 要重复执行的内容。

}

8.2、do...while循

先执行循环体,再进行判断表达式,如果表达式为真,则再次执行循环体,直到表达式为假。至少执行一次。

  • 表达形式:

do

{

循环体语句; ---- 要重复执行的内容。

}while(表达式);

8.3、for循环

  • 表达形式:

for(表达式1;表达式2;表达式3)

{

循环体语句; ---- 要重复执行的内容。

}

表达式1:在整个for循环之前执行一次,且只执行一次,通常用于在for循环初始化条件的值。(可以省去---相当于没有初始化,可在其他位置设置。)

表达式2:循环条件,每次执行循环体前先判断条件是否成立。(满足一次,执行一次,可以省去---相当于条件一直为真。)

表达式3:在执行一次循环体后,就立即执行,(先于下次条件判断,可以省去---相当于在 表达式3 中无操作)通常设置于改变条件。

注意:表达式可以省略,;(分号)必须加上。

8.4、循环的嵌套

在循环体语句中,可能包含另一个循环。外循环执行一次,内循环执行完。

  • 如果循环次数明确------首选for循环;
  • 如果循环次数不明确,需要通过其他条件控制循环------使用while循环;
  • 如果必须先进入循环体,经过循环体运算得到循环控制条件------选择do...while循环。

8.5、break与continue

8.5.1、break

break:结束当前循环,执行循环之后的语句。

while

{

循环体语句1;

break;------从这里结束循环。

循环体语句2;

}

8.5.2、continue

continue:提前结束本次循环,进入下一次条件判断。

while

{

循环体语句1;

continue;------从这里结束本次循环。

循环体语句2;

}

9、函数

函数:一个独立的功能代码模块,在需要使用整个功能时,进行调用,去执行这个功能模块。

库函数:由C语言标准实现的功能模块函数。

自定义函数:在程序中由于可能多次使用某个功能,自己实现这个功能模块函数。

9.1、函数定义

函数包含:函数头与函数体

  • 函数头:对函数的描述说明。

返回值类型:函数功能结束,返回的结果是什么数据类型。

函数名:标识符,表示这个功能的名字,之后使用这个函数名来标识这个功能函数。

参数列表:在编写功能时,存在不确定的值,需要在调用函数时,传入函数。在使用时,根据参数列表情况,调用传递参数列表的值。

写法:数据类型1 变量名1, 数据类型2 变量名2,... ...,数据类型n 变量名n

  • 函数体:功能模块的操作代码 --- 功能实现。
  • 定义方式:

[返回值类型] [函数名] ( [参数列表] )

{

函数体 ---- 函数实现特定功能的过程。

}

9.1.1、无参无返回值

定义方式:

void 函数名()

{

函数体;

}

9.1.2、无参有返回值

定义方式:

返回值类型 函数名([参数列表])

{

函数体;

return 表达式值;

}

return:只要执行到return语句,表示函数功能到这里结束。

return + 值:结束当前函数,同时把值返回到函数调用位置(在调用位置得到函数结果)。

对应有返回值类型,在函数体中必须加上:return + 返回值;

9.1.3、有参无返回值

定义方式:

void 函数名([参数列表])

{

函数体;

}

9.1.4、有参有返回值

定义方式:

返回值类型 函数名([参数列表])

{

函数体;

return 表达式值;

}

9.2、 函数调用

在需要的位置使用这个函数。

调用过程:

当调用时,跳转到对应函数位置进行执行函数功能,当函数功能执行完({}结束或return语句),再跳转回调用位置,继续执行。

9.2.1、无参无返回值调用

函数名();

调用无参函数,则没有参数列表,但小括号不能省略。

9.2.2、无参有返回值调用

函数名();

调用有返回值的函数,在调用位置就会得到函数返回结果。可以通过与返回值类型相同的变量接收返回值,如:ret = 函数名();

9.2.3、有参有返回值调用

函数名(参数值1,参数值2,... ...,参数值n);

在调用时,参数值需要和函数定义的参数列表一 一对应。

在调用时,会把参数值赋给参数列表中的变量。

注意:调用时,参数值可能是变量,表示把变量的值传递给函数的参数列表,而不是把变量直接传递给参数列表。

9.2.4、有参有返回值调用

函数名(参数值1,参数值2,... ...,参数值n);

定义有参函数时,给定的参数列表,在参数列表中的参数,叫做形式参数(形参);调用有参函数时,给定的参数值,叫做实际参数(实参)。

9.3、函数的嵌套调用

在调用一个函数过程中,被调用的函数可以调用另一个函数。

函数的定义是平行的、独立的,不允许嵌套定义。

9.4、函数的声明

编译时提示函数是什么样子的函数。

如果在函数前面调用,在后面位置才进行定义需要在调用前进行声明。

函数声明语法:

返回值类型 函数名([参数列表]);

写法:

返回值类型 函数名(数据类型1 变量名1, 数据类型2 变量名2,... ...,数据类型n 变量名n);

返回值类型 函数名(数据类型1, 数据类型2,... ...,数据类型n);

9.5、递归函数

函数中直接或者间接调用自己这个函数,叫做函数的递归调用,当前函数也叫递归函数。

void fun1()//递归函数 --- 直接调用 
{ 
printf("hello world\n"); 
fun1(); 
} 
void fun2()//递归函数 --- 间接调用 
{ 
printf("nihao\n"); fun3(); 
} 
void fun3() 
{ 
printf("shijie\n"); 
fun2(); 
}

通常递归函数需要有结束条件。

实例:利用递归函数计算阶乘。

#include  //num的阶乘

int factorial(int num)

{

if(num < 1)

return 0;

if(num == 1)

return 1;

return num * factorial(num - 1);

}

int main()
c
{

printf("%d", factorial(5)); //运行结果 120; return 0;

}

10、全局变量与局部变量

1、局部变量

只要在函数内部中定义的变量称为局部变量。函数的形式参数拥有和局部变量一样的性质,即存储期限和块作用域。

  • 局部变量的性质:

自动存储期限(生命周期)。变量的存储期限在变量所在程序区块执行期间有效存储,区间结束或函数返回时,局部变量的值无法保留。

块作用域。局部变量在定义所在程序区块内访问可达,离开区块不可访问。

程序区块:多语句复合构成的程序块,用一对大括号括起来的区域。

2、全局变量

不在任何函数体内部定义的变量,称为全局变量。

  • 全局变量的性质:

静态存储期限,整个程序运行时过程中有效。就如同声明为 static 的局部变量一样,外埠变量拥有静态存储期限。存储在外部变量中的值将永久保留下来,直到整个程序结束。

文件作用域。外部变量拥有文件作用域: 从变量被声明的点开始一直到所在文件的末尾。因此,跟随在外部变量声明之后的所有函数都可以直接访问并修改它。

若想在其他文件中使用需要进行外部声明 extern。

3、变量名的重名

在程序中,如果作用域相同,则变量名不能定义相同。

在不同作用域时,允许定义相同的变量名。如果两个相同变量存在时,默认使用作用域小的变量进行操作。

4、变量的默认值

当变量定义时,如果没有进行初始化,变量的默认值:

局部变量:随机值;

全局变量:默认初始化为 0 ;

总结

        学习c语言已有一两年,最近开始学习嵌入式,又重新学习了c语言,这次的学习,弥补了我之前学习的不足,让我受益匪浅。

在学习C语言的过程中,我积累了一些经验和总结,希望能够与大家分享。

  1. 掌握基础概念:C语言的基础概念是学习的基石,包括变量、数据类型、运算符、控制语句和函数等。通过对这些基础概念的理解和掌握,可以为后续的学习打下坚实的基础。

  2. 学会运用指针:指针是C语言中的重要概念,对于初学者来说可能比较抽象和难以理解。但是,掌握指针的使用可以让我们更加灵活地操作内存和数据,提高程序的效率和性能。

  3. 实践是最好的学习方式:学习理论知识很重要,但是只有通过实际的编程练习才能真正掌握和应用所学的知识。尝试解决实际的问题,并且不断创造和实践新的程序,可以提高编程技能和经验。

  4. 阅读优秀的代码:阅读其他人的代码可以拓宽自己的视野,学习到别人的编程思路和技巧。可以参考一些优秀的开源项目,学习其中的代码结构和设计模式,提升自己的编程水平。

  5. 错误是学习的机会:在编程过程中难免会遇到各种错误和bug,不要气馁和放弃。要学会debug和分析问题的原因,并且从错误中吸取教训。通过解决问题,我们才能真正地提高自己的能力。

  6. 学会使用调试工具:学会使用调试工具,如gdb,在程序运行过程中跟踪变量和代码执行流程,可以帮助我们更快地定位bug并解决问题。

  7. 持续学习和不断实践:C语言的学习是一个长期的过程,要保持持续学习的状态和不断实践的精神。关注最新的编程技术和发展趋势,不断充实自己的知识储备。

总的来说,学习C语言需要坚持不懈的努力和实践,只有通过不断地编程实践和学习,我们才能够真正掌握C语言的精髓,成为一个优秀的C程序员。希望以上总结对正在学习C语言的朋友们有帮助。

你可能感兴趣的:(笔记,c语言)