程序:解决完成特定功能(任务)的流程步骤
计算机程序:让计算机区实现解决问题的步骤执行
计算机语言:计算机能够识别任务的内容(指令)
机器语言:使用0和1表示指令功能
汇编语言:把机器语言指令用助记符进行表示
高级语言:类似自然语言的编写方式
Linux中编写C语言程序。编写工具: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 |
从当前光标开始,使输入的内容替换当前行的内容 |
编译:把C程序编译为计算机能够识别的指令
-o:输出文件重命名。
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修饰指针变量时:
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;
有符号数:把数据中最高位、作为符号位用。0表示正数、1表示负数。
无符号数:数据中,所有位都是数据位,没有符号位。所有无符号数都是正数。
计算机中存储数据以 补码 格式存储。
位:bit,一个单独的0或1二进制 --- 1bit
字节:八位二进制 --- 1Byte, 1B = 8bit
千字节:KByte --- KB
一千个字节 --- 1KB, 1KB = 1000B
在C语言程序中,存在数据,每种数据都有对应的数据类型。C语言是一种静态类型语言。
整数存储:转换为二进制,以补码形式存储。
有无符号:
在计算机中设定的大小:
无符号: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)
无符号: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)
无符号: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)。
无符号:64位(0 ~ 2^64 - 1)
有符号:64位(-2^63 ~ 2^63 - 1)
以LL或ll结尾的整数常量是long long int类型。
定义方式:符号关键字 + 尺寸关键字
以二进制补码形式存储:数据部分 + 指数部分
符号位 + 阶码(指数幂) + 尾数(数据值)
符号位(1位) + 阶码(8位) + 尾数(23位)为了表明只需要单精度,可以在常量的末尾处加上字母F或f。如57.0F。
符号位(1位) + 阶码(11位) + 尾数(52位)
若为了以long double存储,可以在常量的末尾处加上字母L或l。如57.0L。
判断小数相等:0.000001> 小数1 - 小数2 > -0.000001
字符型(char)
对于字符型数据,在计算机中存储,依旧使用二进制0和1表示。
在C语言中,使用ASCII码来表示(整数)----8位(8bit),1B
表示方法:用单引号包括
字符类型可以当做整数进行操作。
数组:由多个数据组成一个数据集合,在集合中存在多个数据内容。
类型 数组名[数组长度];
类型:每个数据的类型。
数组名:整个数据集合的名字。
数组长度:数据集合中的数据个数;数组长度应该为常量。
占用内存空间:类型 * 数组长度。
以连续的内存空间创建数组,每个数字元素是相邻的。
为了存取特定的数组元素,可以在写数组名的同时在后边加上一个用方括号围绕的整数值(称这是对数组取下标或索引)。
格式:数组名[ 下标值 ];
下标值是数组元素在数组中的位置,也叫索引值;下标值为整型。
下标值取值范围: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;
}
二维数组是一维数组的集合,集合中的数组元素是一维数组。
数据类型 数组名[ 常量表达式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 ] = {初始化};
由于基本数据类型不能满足需要,需要把多个的数据类型进行组合,共同表示新的复合数据,形成新的类型。构造新的数据类型的方式就叫做构造类型。
使用多种数据类型作为成员,进行组合,构成新的类型,就叫做结构体。
struct 结构体名
{
类型1 成员1;
类型2 成员2;
... ...
};
在程序中添加一种新的类型,不占用内存空间,只是说明在程序中有一种新类型。
数据类型 变量名;
数据类型:struct 结构体名
结构体变量名.成员名;
使用多种数据类型作为成员,进行组合,但是使用同一段空间进行存储(多个成员共用一个空间),构成的新的类型,就叫做共用体(联合体)。
使用共用体的问题:同一时刻只能存储一个成员。
所占存储空间为占用最大空间的成员的空间。
union 共用体名
{
类型1 成员1;
类型2 成员2;
... ...
};
共用体用法与结构体相同。
在定义一种新类型时,这个类型能够取值的范围是确定的,通过这个定义的新类型把能够取值的范围一一列举出来,这种类型就叫做枚举。
声明枚举类型:
enum 枚举名
{
成员1,
成员2,
成员3,
... ...
};
枚举类型中,每个成员代表能够取的一个值。
声明类型时,如果成员没有赋值,成员就等于上一个成员的值+1;如果成员1没有赋值,则为0;
enum 枚举名 变量名;
使用:变量名 = 成员;
内存地址:在内存中,对于每一个字节都分配了一个唯一的编号,用于区别不同的位置。每个字节都有唯一的地址。用来和内存中的其他字节相区别。
指针:在内存空间(定义变量)中申请空间用来存储地址,就叫做指针,也叫指针变量。
指针变量的定义:数据类型 *指针变量名
数据类型:储存哪种数据类型的地址,就指向哪种类型,因此要存储那种数据类型的地址,就定义哪种数据类型。
指针变量的使用:指针变量 = 地址(&变量名)(要求地址的空间能够使用,&取地址符)
指针所指向空间数据的访问:*指针名
void:空类型,表示没有数据类型。
void不能定义变量。
常量
含义:在整个程序中都不会进行改变的数据。
变量
含义:在整个程序中可以进行变化的数据,在内存中存储数据后,空间中的数据值可以进行改变。
先定义变量才能使用。
存储类型
(栈区,由系统进行管理),可以省略。
static修饰局部变量:
延长生命周期为整个程序(程序结束变量的生命周期结束),但作用域不变,只能在定义的作用域中使用。
当多次定义static的1局部变量时,只会定义第一次,其余的跳过定义。
static修饰全局变量:
设置为静态变量,只能在本文件内使用这个变量,其它文件无法使用。
未初始化变量,将初始化为0。
存储到CPU中(没存入,通常等同于auto)
变量名
使用标识符表示变量名。
变量初始化
在定义变量时,为变量赋初始值。
由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 |
十六进制所代表的任意字符 |
三位八进制 |
功能:输出应该字符。
功能:输出字符串,输出完成自动换行。
输入功能,从键盘输入数据给变量。使用scanf需包含头文件#include
格式:scanf("格式化字符1,格式化字符2",输入列表);
格式化字符:格式化字符位置匹配的内容输入到变量中。
例:scanf("%d", &a);
输入列表:列表要输入的变量。
输入失败返回 0 ,成功返回 1;
注意:如果是连续两个数值格式化字符,在键盘输入时,需要隔开,通过空格回车。
处理输入函数留下的垃圾:1、用getchar(); 2、scanf("%*c%c", &ch);
scanf("%[^\n]", &ch); // 检测到回车停止输入,通常用于连续输入字符串。
功能:从键盘输入字符串,以回车结束输入。输入长度应小于数组长度。
功能:从键盘读取一个字符。
返回值:
正常输入,则返回读取的代码值;
异常输入或结束键盘输入,则返回 -1 / EOF(ctrl d)。
只要是使用运算符进行运算时,都会有结果。
+:加、-:减、*:乘、/:除、%:取余
进行运算时,如果是同种类型数据进行运算,则结果为对应类型。
隐式类型转换
在进行各种运算操作,如果是不同的数据类型,会把不同的数据类型转换为相同的数据类型,然后再进行运算。(原则:精度低往精度高的类型转换)
强制类型转换
把数据的值取出,然后指定转换为某种类型,原数据不变。格式:(要转换的类型)数据
优先级
(乘、除、取余) 高于 (加、减) >>> 同级的至左向右。
赋值运算符表达格式:变量 = 操作数;
赋值运算结果为所赋的值。
关系运算符是进行比较运算,判断关系是否成立(比较左右两边的表达式是否满足关系),成立为真(值:1),不成立为假(值:0)
注意:在进行运算时,如果有连续的多个运算符,单一运算符之后得到结果再与下一个运算符进行运算。
优先级:(>、>=、>> 关系运算符低于算术运算符
连接两个表达式,根据表达式的真假进行组合得到新的结果,结果也为真或假。
有假则假,全真为真。
有真则真,全假为假。
取反(是真则假,是假则真)。
优先级:! 高于 (&&、||)
位运算对数据中对应的二进制位进行操作。(不会涉及到符号位的说法)
有0则0,全1为1。
有1则1,全0为0。
相同为0,相异为1。
有1则0,有0则1.
数据值<<移动位数将一个数据所有二进制位向左移动若干位数,高位部分移出,低位部分补零。
数据值>>移动位数将一个数据所有二进制位向右移动若干位数,高位部分原先为1则补1(原先为0则补0),低位部分舍去。
(+=、-=、*=、/=、%=)、(|=、&=、^=)
表达方式:变量 += 表达式 >>> 变量 = 变量 + 表达式
++、--
依次运算每个表达式,并将最后一个表达式的结果作为整个逗号运算符的结果。
优先级:所有优先级中最低。
sizeof()运算符的运算结果为长整型。
优先级 |
运算符 |
名称或含义 |
使用形式 |
1 |
[] |
数组下标 |
数组名[常量表达式] |
() |
圆括号 |
(表达式) / 函数名(形参表) |
|
. |
成员选择(对象) |
对象.成员名 |
|
-> |
成员选择(指针) |
对象指针->成员名 |
|
2 |
- |
负号运算符 |
-表达式 |
~ |
按位取反运算符 |
~表达式 |
|
++ |
自增运算符 |
变量名 / 变量名 |
|
-- |
自减运算符 |
--变量名 / 变量名-- |
|
* |
取值运算符 |
*指针变量 |
|
& |
取地址运算符 |
&变量名 |
|
! |
逻辑非运算符 |
!表达式 |
|
(类型) |
强制类型转换 |
(数据类型)表达式 |
|
sizeof |
长度运算符 |
sizeof(表达式) |
|
3 |
/ |
除 |
表达式 / 表达式 |
* |
乘 |
表达式 * 表达式 |
|
% |
余数(取模) |
整型表达式 % 整型表达式 |
|
4 |
+ |
加 |
表达式 + 表达式 |
- |
减 |
表达式 - 表达式 |
|
5 |
左移 |
变量 |
|
>> |
右移 |
变量 >> 表达式 |
|
6 |
> |
大于 |
表达式 >表达式 |
>= |
大于等于 |
表达式 >= 表达式 |
|
小于 |
表达式 < 表达式 |
||
小于等于 |
表达式 |
||
7 |
== |
等于 |
表达式 == 表达式 |
!= |
不等于 |
表达式 != 表达式 |
|
8 |
& |
按位与 |
表达式 & 表达式 |
^ |
按位异或 |
表达式 ^ 表达式 |
|
| |
按位或 |
表达式 | 表达式 |
|
9 |
&& |
逻辑与 |
表达式 && 表达式 |
|| |
逻辑或 |
表达式 || 表达式 |
|
10 |
?: |
条件运算符 |
表达式1 ? 表达式2 : 表达式3 |
11 |
= |
赋值运算符 |
变量 = 表达式 |
/= |
除后赋值 |
变量 /= 表达式 |
|
*= |
乘后赋值 |
变量 *= 表达式 |
|
%= |
取模后赋值 |
变量 %= 表达式 |
|
+= |
加后赋值 |
变量 += 表达式 |
|
-= |
减后赋值 |
变量 -= 表达式 |
|
左移后赋值 |
变量 >>= 表达式 |
||
>>= |
右移后赋值 |
变量 >>= 表达式 |
|
&= |
按位与后赋值 |
变量 &= 表达式 |
|
^= |
按位异或后赋值 |
变量 ^= 表达式 |
|
|= |
按位或后赋值 |
变量 |= 表达式 |
|
12 |
, |
逗号运算符 |
表达式1, 表达式2,……,表达式n |
根据实际的情况条件,选择性执行或不执行某些功能。
根据条件,如果满足条件,则执行对应的功能操作代码,执行完后,继续往下执行;否则就跳过对应功能代码继续往下执行。
if(条件表达式)
{
语句块;
} ---- {}满足if范围的语句块,如果语句块只有一条,{}可省略。
条件表达式:只计算表达式的结果为 真(非0) 或 假(0),如果满足条件,则执行语句块。
满足条件表达式,执行一段语句功能内容,不满足则执行另一段功能内容;之后继续往下执行。
if(条件表达式)
{
语句块1;
}else{
语句块2;
}
多种情况选择执行一种,判断第一种是否满足,满足则执行,不满足则判断下一种是否满足,满足则执行,不满足继续判断。
if(条件表达式)
{
语句块1;
}else if{
语句块2;
}
... ...
else{
语句块n;
}
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中语句块。
}
注意:表达式和常量表达式结果为整型。
重复多次执行某个功能。
表达式为真,则执行一次循环体语句,再次判断表达式是否为真,为真则再次执行,直到表达式为假就跳出循环。
while(表达式)
{
循环体语句; ---- 要重复执行的内容。
}
先执行循环体,再进行判断表达式,如果表达式为真,则再次执行循环体,直到表达式为假。至少执行一次。
do
{
循环体语句; ---- 要重复执行的内容。
}while(表达式);
for(表达式1;表达式2;表达式3)
{
循环体语句; ---- 要重复执行的内容。
}
表达式1:在整个for循环之前执行一次,且只执行一次,通常用于在for循环初始化条件的值。(可以省去---相当于没有初始化,可在其他位置设置。)
表达式2:循环条件,每次执行循环体前先判断条件是否成立。(满足一次,执行一次,可以省去---相当于条件一直为真。)
表达式3:在执行一次循环体后,就立即执行,(先于下次条件判断,可以省去---相当于在 表达式3 中无操作)通常设置于改变条件。
注意:表达式可以省略,;(分号)必须加上。
在循环体语句中,可能包含另一个循环。外循环执行一次,内循环执行完。
break:结束当前循环,执行循环之后的语句。
while
{
循环体语句1;
break;------从这里结束循环。
循环体语句2;
}
continue:提前结束本次循环,进入下一次条件判断。
while
{
循环体语句1;
continue;------从这里结束本次循环。
循环体语句2;
}
函数:一个独立的功能代码模块,在需要使用整个功能时,进行调用,去执行这个功能模块。
库函数:由C语言标准实现的功能模块函数。
自定义函数:在程序中由于可能多次使用某个功能,自己实现这个功能模块函数。
函数包含:函数头与函数体
返回值类型:函数功能结束,返回的结果是什么数据类型。
函数名:标识符,表示这个功能的名字,之后使用这个函数名来标识这个功能函数。
参数列表:在编写功能时,存在不确定的值,需要在调用函数时,传入函数。在使用时,根据参数列表情况,调用传递参数列表的值。
写法:数据类型1 变量名1, 数据类型2 变量名2,... ...,数据类型n 变量名n
[返回值类型] [函数名] ( [参数列表] )
{
函数体 ---- 函数实现特定功能的过程。
}
定义方式:
void 函数名()
{
函数体;
}
定义方式:
返回值类型 函数名([参数列表])
{
函数体;
return 表达式值;
}
return:只要执行到return语句,表示函数功能到这里结束。
return + 值:结束当前函数,同时把值返回到函数调用位置(在调用位置得到函数结果)。
对应有返回值类型,在函数体中必须加上:return + 返回值;
定义方式:
void 函数名([参数列表])
{
函数体;
}
定义方式:
返回值类型 函数名([参数列表])
{
函数体;
return 表达式值;
}
在需要的位置使用这个函数。
调用过程:
当调用时,跳转到对应函数位置进行执行函数功能,当函数功能执行完({}结束或return语句),再跳转回调用位置,继续执行。
函数名();
调用无参函数,则没有参数列表,但小括号不能省略。
函数名();
调用有返回值的函数,在调用位置就会得到函数返回结果。可以通过与返回值类型相同的变量接收返回值,如:ret = 函数名();
函数名(参数值1,参数值2,... ...,参数值n);
在调用时,参数值需要和函数定义的参数列表一 一对应。
在调用时,会把参数值赋给参数列表中的变量。
注意:调用时,参数值可能是变量,表示把变量的值传递给函数的参数列表,而不是把变量直接传递给参数列表。
函数名(参数值1,参数值2,... ...,参数值n);
定义有参函数时,给定的参数列表,在参数列表中的参数,叫做形式参数(形参);调用有参函数时,给定的参数值,叫做实际参数(实参)。
在调用一个函数过程中,被调用的函数可以调用另一个函数。
函数的定义是平行的、独立的,不允许嵌套定义。
编译时提示函数是什么样子的函数。
如果在函数前面调用,在后面位置才进行定义需要在调用前进行声明。
函数声明语法:
返回值类型 函数名([参数列表]);
写法:
返回值类型 函数名(数据类型1 变量名1, 数据类型2 变量名2,... ...,数据类型n 变量名n);
返回值类型 函数名(数据类型1, 数据类型2,... ...,数据类型n);
函数中直接或者间接调用自己这个函数,叫做函数的递归调用,当前函数也叫递归函数。
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;
}
只要在函数内部中定义的变量称为局部变量。函数的形式参数拥有和局部变量一样的性质,即存储期限和块作用域。
自动存储期限(生命周期)。变量的存储期限在变量所在程序区块执行期间有效存储,区间结束或函数返回时,局部变量的值无法保留。
块作用域。局部变量在定义所在程序区块内访问可达,离开区块不可访问。
程序区块:多语句复合构成的程序块,用一对大括号括起来的区域。
不在任何函数体内部定义的变量,称为全局变量。
静态存储期限,整个程序运行时过程中有效。就如同声明为 static 的局部变量一样,外埠变量拥有静态存储期限。存储在外部变量中的值将永久保留下来,直到整个程序结束。
文件作用域。外部变量拥有文件作用域: 从变量被声明的点开始一直到所在文件的末尾。因此,跟随在外部变量声明之后的所有函数都可以直接访问并修改它。
若想在其他文件中使用需要进行外部声明 extern。
在程序中,如果作用域相同,则变量名不能定义相同。
在不同作用域时,允许定义相同的变量名。如果两个相同变量存在时,默认使用作用域小的变量进行操作。
当变量定义时,如果没有进行初始化,变量的默认值:
局部变量:随机值;
全局变量:默认初始化为 0 ;
学习c语言已有一两年,最近开始学习嵌入式,又重新学习了c语言,这次的学习,弥补了我之前学习的不足,让我受益匪浅。
在学习C语言的过程中,我积累了一些经验和总结,希望能够与大家分享。
掌握基础概念:C语言的基础概念是学习的基石,包括变量、数据类型、运算符、控制语句和函数等。通过对这些基础概念的理解和掌握,可以为后续的学习打下坚实的基础。
学会运用指针:指针是C语言中的重要概念,对于初学者来说可能比较抽象和难以理解。但是,掌握指针的使用可以让我们更加灵活地操作内存和数据,提高程序的效率和性能。
实践是最好的学习方式:学习理论知识很重要,但是只有通过实际的编程练习才能真正掌握和应用所学的知识。尝试解决实际的问题,并且不断创造和实践新的程序,可以提高编程技能和经验。
阅读优秀的代码:阅读其他人的代码可以拓宽自己的视野,学习到别人的编程思路和技巧。可以参考一些优秀的开源项目,学习其中的代码结构和设计模式,提升自己的编程水平。
错误是学习的机会:在编程过程中难免会遇到各种错误和bug,不要气馁和放弃。要学会debug和分析问题的原因,并且从错误中吸取教训。通过解决问题,我们才能真正地提高自己的能力。
学会使用调试工具:学会使用调试工具,如gdb,在程序运行过程中跟踪变量和代码执行流程,可以帮助我们更快地定位bug并解决问题。
持续学习和不断实践:C语言的学习是一个长期的过程,要保持持续学习的状态和不断实践的精神。关注最新的编程技术和发展趋势,不断充实自己的知识储备。
总的来说,学习C语言需要坚持不懈的努力和实践,只有通过不断地编程实践和学习,我们才能够真正掌握C语言的精髓,成为一个优秀的C程序员。希望以上总结对正在学习C语言的朋友们有帮助。