本文包含Linux系统,Vim编辑器,C语言,编译器和gcc的介绍
Linux系统介绍:
1970年 贝尔实验室的研究员 肯.汤普逊 丹尼斯.里奇 使用BCPL语言给实验室中空闲的计算机编写一个操作系统,在编写过程发现BCPL并不好用,因此把这门语言升级成了newB,之后又对它进行完善,采用这个语言的第二个字母,因此叫C语言。
之后又用C语言开发了一款通用的操作系统UNIX,之后一些计算机专家又UNIX精简成了MiniX,用于教育、学习、研究、交流,芬兰的研究生林纳克斯.托瓦斯学习了这门课程后,仿照Minix写出了Linux最初的代码,之后把它公共的开源网站上,经过全世界的程序员把进行了完善。
Linux文件系统:
从用户角度来看Linux就一个分区(管理硬盘的能力较强),它的最顶级目录叫根目录/,根目录下的内容有:
bin 存储的一些系统命令的可执行文件
boot 存储着系统启动时所需要文件
dev 存储着一些硬件的设备文件,在UNIX/Linux系统中一切皆文件
etc 存储着系统、软件的配置文件
home 用户目录,系统会为每个用户在home目录创建一个以它用户名命名的目录,用户对这个目录有绝对的控制权
lib 存储着一些代码库,以.so、.a结尾文件,类似windows系统中的.dll文件
media 多媒体文件夹,挂载的U盘、虚拟光盘、共享文件夹都在这个目录下
mnt 通过网络共享的目录文件,会被映射到这个目录下
opt 用户安装的应用软件一会安装在这个目录
proc 该目录中是系统记录每个正在运行的程序相关情况的目录
root 超级用户相关的文件,ubuntu系统默认不开户该用户
run 存储系统运行过程中相关的文件和数据
sbin 存储的是一些管理员用户才能使用系统命令的可执行文件
sys 存储着系统的一些设备驱动
tmp 存储系统运行过程中产生的临时文件
usr 存储着编程所需要的头文件、库文件等
var 存储着系统的些备份和日志相关内容
Linux系统命令:
终端的使用技巧:
Ctrl+Alt+T 快速打开终端
Shift+Ctrl+T 新建终端标签页
Tab 补全命令或参数,如果有多个候选,连续按两下Tab可以列出所有候选。
up/down 调用命令的执行记录
home 光标跳转到行首
end 光标跳转行尾
!cmd 把最近一次执行cmd的记录再执行一次
常用命令:
clear 清屏功能,Ctlr+l也具备同样的功能
ls 显示当前目录下的内容
-a 显示隐藏的文件,在Linux、UNIX系统下以.开头的文件默认是隐藏的,在界面中使用Ctrl+h可以显示隐藏.开头的文件。
-l 显示文件的详细信息
cd <path> 进入一个目录(切换工作目录)
~ 当前用户的主目录
/ 根目录
. 当前目录
.. 上级目录
man [n] <key> 查看某个关键字的帮助手册,key可以是命令也可以是函数名
n=1 系统命令
n=2 系统函数
n=3 标准库函数
q 退出帮助手册
sudo reboot 系统重启命令
sudo init 0 系统关机命令
size <exec> 查看可执行文件的内存段
time <exec> 记录可执行文件的执行时间
strace <exec> 追踪可执行文件的执行过程
pwd 查看当前所在的工作目录
whoami 查看当用户的用户名
文件相关的命令:
touch <filename> 创建文件
rm <filename> 删除文件,删除时不经过回收站,很难恢复,删除文件时要慎重。
cp <src> <dest/>[filename] 复制文件
mv <src> <dest/>[filename] 移动文件,它还具有重命名的功能。
cat <filename> 显示文件的所有内容到屏幕,只适合显示内容较少的文件。
more <filename> 默认显示文件的第一页内容,回车向下翻一行,空格键向下翻一页,q键退出。
head <filename> 显示文件的前10行内容
tail <filename> 显示文件的最后10行内容
目录相关命令:目录就是特殊的文件
mkdir <dirname> 创建目录
-p 可以创建多级目录
rmdir <dirname> 删除空目录
rm -rf <dirname> 删除非空目录
cp -frp <srcdir> <destdir> 复制目录
mv 移动和重命名目录,不需要加额外的参数
网络相关命令:
ifconfig 查看网络的配置信息,windows系统下使用ipconfig
sudo ifconfig <网卡名> down 禁用网卡
sudo ifconfig <网卡名> up 启用网卡
sudo ifconfig <网卡名> xxx.xxx.xxx.xxx netmask 255.255.255.xxx 配置ip地址和子网掩码
ping ip地址或域名 测试网络是否连通,Ctrl+c结束测试
ping www.baidu.com 测试是否能上外网
ping 网关地址 测试与交换机、路由器是否连通
ping 127.0.0.1 测试回环,如果该地址不通说明你的网卡没有正常工作
ping 同事的ip地址
telnet xxx.xxx.xxx.xxx 登录远程服务器
输入用户名:
输入密码:
采用明文传输数据,安全性低,但速度快,一般公司内部采用这种方式登录。
ssh <用户名>@xxx.xxx.xxx.xxx 首次登录会问你是否保存密钥
ssh student@47.97.229.46
密码:zzxx
exit 退出
采用加密传输数据,安全性高,一般通过外网访问时,会使用这种方式。
其它命令:
chmod 修改文件权限
ls -l 查看当前目录下所有文件的权限
drwxrwxr-x 第一个字符代表文件的类型,2~4文件主人的权限,5~7与文件主人同组的用户权限,8~10其它用户的权限。
r 读权限
w 写权限
x 执行权限
chmod的用法1:
chmod +|- r/w/x <filename>
所有用户一起增加或删除某一项权限
chmod的用法2:
chmod mmm <filename>
第一个m代表文件主人的权限,对应2~4
第二个m代表与文件主人同组的用户权限,对应5~7
第三个m代表其它用户的权限,8~10
m = r4+w2+x1
ln <链接目标> <新建的链接文件> 创建链接文件,类似windows下的快捷方式。
默认创建硬链接文件,它链接是文件的内存,当链接被删除后,链接文件依然能正常访问。
加-s参数创建的是软链接,当链接目标被删除后,链接文件不能再访问,与windows下的快捷方式一模一样。
注意:目录文件只能创建软链接,以我的虚拟机为例,ln /media/sf_share/ ~/share -s 给共享目录创建了一个软链接。
find [path] -name <filename> 按文件名在指定目录下查找文件
grep <"key"> <path/filename> 根据文件的内容查找文件
tar 压缩/解压文件
tar -zcvf pack.tar.gz <...> 压缩文件
tar -zxvf pack.tar.gz 在当前目录下解压文件
tar -zxvf pack.tar.gz -C <path> 解压到指定目录下
通配符、管道、重定位:
通配符:* ?
* 在命令行中代表任意多个字符
? 在命令行中代表任意一个字符
grep "key" /* -R 查找系统中所有文件内容是否有"key" */
管道:把命令的执行结果当作另一个命令的数据源,把两个命令通过一个管子连接到一起。
ls -a | grep "key"
find / | grep "key"
重定位:把命令的执行结果写入到文件中
cmd > filename 如果filename文件中有内容则先清空,filename文件不存在则创建,再把cmd命令的执行结果写入到filename文件中。
cmd >> 把cmd命令的执行结果追加到filename文件中。
Linux系统命令总结:
前提:
1、我们写的代码绝大多数运行在Linux服务器上。
2、工作时使用的Linux服务器不带界面,只能使用命令操作。
要求:
1、常用的Linux命令必须掌握,要经常使用。
2、文件相关、目录相关的命令,平时可以用鼠标键盘操作替代。
3、网络相关命令会在学习网络编程时大量使用,暂时了解即可。
4、其它命令、通配答、管道、重定位,在后期的学习过程中、工作时可能用到,了解即可。
vim文本编辑器:可以在没有界面的情况下,写代码的一个工具。
sudo apt-get install vim
它有一个自带的教程:vimtutor,中午抽时间看一下。
vi文本编辑器:
是一款可以无界面的情况下编写代码的工具,所有UNIX、Linux系统自带的都有,通用性强。
可以进行自定义、二次开发,被称为成长型的神器,vim是vi的增强版,一般Linux系统需要手动安装,ubuntu系统的安装指令是:sudo apt-get install vim。
vim的简单用法:
1、vim filename.c 文件如果存在则打开,不存在就会创建。
2、按i键,可以编辑内容。
3、编辑完成后按ESC键退出编辑,按两下ZZ(Shift+z)保存退出。
vim的三大主要模式和模式切换:
正常模式:是进入vim的默认模式,主要用于阅读文件,或通过快捷键修改文件。
插入模式:主要用于编辑文件的内容。
行底模式:主要用于对vim进行一些设置,或执行一些命令。
模式切换方法:
正常模式切换到插入模式:i
插入模式切换加正常模式:ESC、Ctrl+c
正常模式切换到行底模式:输入冒号
行底模式切换加正常模式:ESC、Ctrl+c
注意:插入模式与行底模式之间不能直接切换,必须经过正常模式中转。
正常模式下的操作:
在行底模式下:set nu 显示行号
光标移动:
h左 j下 k上 l右 光标的上下左右移动,在vim中可以使用方向键移动,但在vi中只能使用hjkl。
page down 光标向下跳转一页。
page up 光标向上跳转一页。
home 光标跳转到行首
end 光标跳转到行尾
gg 光标跳转到文件的最后一行
G 光标跳转到文件的第一行
nG 光标跳转到第n行
n+up 光标向上跳转n行
n+down 光标向下跳转n行
vim file.c +n 进入vim后光标跳转到第n行
删除内容:
x 删除一个字符
nx 删除n个字符
dw/de 删除一个单词
dd 删除一行
ndd 删除n行
d$/D 从当前光标位置删除到行尾
d^ 从当前光标位置删除到行首
复制内容:
yw/ye 复制一个单词
yy/Y 复制一行
nyy 复制n行
y$ 从当前光标位置复制到行尾
y^ 从当前光标位置复制到行首
p 把复制的内容粘贴光标的后面 小写
P 把复制的内容粘贴光标的前面 大写
移动内容:
删除的内容还存在在缓冲区,使用p/P粘贴到新位置,就达到了移动内容的效果。
替换内容:
r<x> 把光标所在的字符替换成<x>
cw/ce 替换一个单词(删除单词进入插入模式)
R 进入替换模式,按ESC、Ctrl+c退出替换模式。
xp 可以快速调换两字符的位置。
撤销操作:
u 撤销一次操作,可以连续使用多次
U 撤销当前行的所有操作,回到最初状态,但只能撤销一次。
Ctrl+r 取消撤销操作
进入插入模式的多种方法:
i 在当前光标的前面进入插入模式
I 光标跳转到行首进入插入模式
a 在当前光标的后面进入插入模式
A 光标跳转到行尾进入插入模式
o 在光标下面添加一个空白行,然后进入插入械
O 在光标上面添加一个空白行,然后进入插入械
查找内容:
/key+Enter n向下查找,N向上查找
保存退出:ZZ
插入模式下的操作:
该模式主要用于编辑内容,快捷键不多。
Ctrl+i 相当于Tab键的功能,用于代码缩进。
Ctrl+j 相当于回车键的功能
Ctrl+c 相当于ESC键的功能
Ctrl+h 相当于Backspace键的功能。
Ctrl+p/n 自动补全,写代码时非常好用
行底模式下的操作:
!cmd 执行系统命令。
w 保存内容
q 退出,如果内容有发生修改,用q无法退出
wq 保存退出
q! 强制退出
x 保存退出,但只保存内容
X 加密,wq保存密码退出
set key= , wq保存退出,会删除掉密码
%s/old/new 全文替换,会在下方告诉你替换了多少次
>n 从光标所行开始,下面n行代码向右缩进
<n 从光标所行开始,下面n行代码向左缩进
set nu 显示行号
set nonu 不显示行号
注意:在行底模式下对vim进行的设置,只是临时有效,vim退出后就失效了,要想长期有效就要把这些设置命令写入vim的配置文件,vim的配置文件在:~/.vimrc
" 显示行号
set number
" 设置制表符的宽度为4个空格
set tabstop=4
" 设置自动缩进
set autoindent
" 设置智能缩进
set smartindent
" 设置缩进的宽度为4个空格
set shiftwidth=4
" 设置自动保存
set autowrite
" 不产生临时文件
set noexpandtab
" 自定义一个保存退出功能函数
func SaveExit()
exec "wq"
endfunc
" 映射正常模式下的Ctrl+z快捷键,调用保存退出函数
map <C-z> :call SaveExit() <CR>
" 映射插入模式下的Ctrl+z快捷键,调用保存退出函数
imap <C-z> <ESC>:call SaveExit() <CR>
" 自定义一个编译并执行函数
func RunCode()
exec "w"
if "c"==&filetype
exec "!gcc % && ./a.out"
endif
endfunc
" 映射正常模式下的Ctrl+x快捷键,调用编译执行函数
map <C-x> :call RunCode() <CR>
" 映射插入模式下的Ctrl+x快捷键,调用编译执行函数
imap <C-x> <ESC>:call RunCode() <CR>
" 自定义一个插入main和头的函数
func InsertMain()
call setline(1,"#include <stdio.h>")
call setline(2,"")
call setline(3,"int main(int argc,const char* argv[])")
call setline(4,"{")
call setline(5,"\t")
call setline(6,"\treturn 0;")
call setline(7,"}")
exec "5"
endfunc
" 当创建新的.c文件时自动调用InsertMain函数 "
autocmd BufNewFile *.c :call InsertMain()
C语言介绍:
丹尼斯.里奇和肯.汤普逊于1971~1973年在贝尔实验室,在开发UNIX操作系统时,以BCPL语言为基础开发世界上第一款高级编程语言,它是为了编写操作系统而开发的编程语言,主要特点是:语法简单,只有32个关键字,运行速度快,拥有媲美汇编的运行速度,适合实现底层的算法,控制硬件的能力强,也适用于嵌入式、单片机开发。
为什么学习C语言:
1、是第一款高级编程语言,之后的高级编程语言在设计时基本上都参考了它,例如:C++、C#、Java、Objective-C、PHP、Go等,这些语言也被称为C语系的编程语言。
2、学习了C语言能够了解编程的本质,快速掌握其它的编程语言。
3、并且学习C语言还能帮助我们理解计算机的底层逻辑、运行机制、管理规则,为以后的工作学习打下基础。
第一个C程序:
#include <stdio.h>
int main(int argc,const char* argv[])
{
printf("Hello World!\n");
return 0;
}
1、程序员编写的C代码不是标准的C代码,需要一段程序把它翻译成标准的C代码,负责翻译的程序叫预处理器,被翻译的指令叫预处理指令,以#开头的都是预处理指令。
2、#include 是个预处理指令,它的功能是导入一个辅助文件。
#include <> 从系统指定的路径查找并导入一个辅助文件。
#include "" 先从当前路径下查找并导入一个辅助文件,如果当路径下没有再从系统指定的路径查找并导入一个辅助文件。
3、C语言标准委员会为C语言提供了一些基础功能,这些功能以函数形式被封装在libc.so库文件中,同时还提供一些对函数的说明文件(头文件),这此头文件存储在/usr/include/路径下,常用的头文件在:stdio.h stdlib.h string.h math.h等。
standard input output head file -> stdio.h 这头文件中是对输入、输出类的函数的使用方法,方便编译器检查调用的是否正确。
4、C语言中以main函数(C语言中的函数就是一段代码,与数学中函数的意思不同)作为程序的执行入口,有且只能有一个,无论写在任何位置它都第一个执行。
5、int是一种数据类型(编程语言把日常生活中使用的数据进行了分类),写在这个位置表示main函数的执行结果是一个整数。
6、argc、argv是程序执行时,通过命令行提供的参数,后续会详细讲解。
7、C语言中使用大括号划分代码区域,写在大括号内的都属性main函数。
8、printf/scanf是标准库中的函数,具有输入、输出数据的功能,使用它们需要包含stdio.h头文件,一般用于测试程序。
9、计算机中把一些不方便使用或显示的字符用一些特殊符号表示(转义字符)
\n 换行
\r 光标回到行首
\b 光标左移
\a 铃
\t 制表符
%% 显示一个%
\\ 显示一个\
10、C语言以 ; 作为一行代码的结束标志,过长的代码可以换行。
11、return 结束函数的执行,并返回一个数据给函数的调用者。
12、main函数中返回的整数,会被操作系统获取到,它表示程序是以什么状态结束的
0 代表程序正常结束
负数 代表程序执行过程中出现错误(程序员写的代码出现错误)
正数 代表程序执行过程中出现异常(程序的运行环境出现问题,与程序员无关)
echo $? 可以使用此命令查看main函数的返回值
编译器和gcc:
什么是编译器:它是一个负责翻译的程序,它可以把人类能看懂的代码翻译成计算机能理解的二进制指令,它由预处理器、汇编器、编译器、链接器组成。
gcc是GNU组织为了编译Linux内核而开发一款C语言编译器。
以gcc为例,编译器是如何把C代码翻译成可执行的程序(面试时问的很多):
1、把程序员所编写的C代码翻译成标准的C代码
gcc -E hello.c 会把预处理的果显示在屏幕上
gcc -E hello.c -o hello.i 会把预处理的结果保存到hello.i文件中,以.i结尾的文件也叫处理文件
2、把预处理的结果翻译成汇编代码
gcc -S hello.i 会生成以.s结尾的汇编文件
3、把汇编代码翻译成二进制指令
gcc -c hello.s 会生成以.o结尾的目标文件(二进制的)
4、把若干个目标文件合并成一个可执行的程序
gcc a.o b.o c.o ... 默认会生成一个叫a.out的可执行程序
./a.out 执行程序
注意:gcc head.c 包含了以上四个步骤,gcc hello.c && ./a.out 编译并执行。
gcc编译器常用的参数:
-E 预处理
-S 生成汇编文件
-c 生成目标文件
-o 设置输出文件的名字,例如:gcc hello.c -o hello
-I 指定头文件的路径,多文件编程时使用
-l 指定要链接库名,例如:sqrt、pow等数学函数,需要额外链接数学库,gcc math.c -lm
-L 指定要链接库的路径
-D 编译时定义宏
-g 编译时添加调试信息,这样编译出的可执行程序,可以使用gdb进行调试
-Wall 显示代码中所有警告,编译时会变得非常严格,工作时、写项目需要添加的参数
-Werror 把警告当作错误,只要代码中有警告,就无法生成可执行程序
-std 指定编译时的语法标准,C语言的语法标准有:c89、c99、c11、c21
-std=gnu89、-std=gnu99、-std=gnu11
C语言的文件类型:
.h 头文件
.c 源文件
.i 预处理文件
.o 目标文件
.s 汇编文件
.a 静态库文件
.so 动态库文件,相当于windows系统里的.dll
.gch 头文件的编译结果,没什么用,建议立即删除
C语言的基本数据类型:
整型:
有符号整型:最高位的二进制位用来表示正负,0代表整数,1代表负责。
由于编程时使用的较多,所以编译器允许 signed 不加就代表加,可以省略。
无符号整型:所以有二进制位都用来表示数据,因此只能表示正数。
在使用时 unsigned 关键字不能省略,所以比较麻烦,C语言的标准委员会为了我们方便使用无符号整型,在stdin.h头文件中对无符号整型进行了重定义。
uint8_t,uint16_t,uint32_t,uint64_t
注意:signed long、unsigned long 在32位系统下是4字节,64位系统下是8字节。
浮点型:小数点是浮动,也就是带小数点的数据。
小数后六位有效,采用科学计算法存储,由:符号位+底数位+指针数构成,由于格式比较特殊所以在使用时需要进行格式转换,所以运算速度比整型慢,编程时尽量少用。
模拟:
布尔:由于先出现的C语言,后有的布尔类型,所以在设计C语言时没有设计布尔类型,之后C语言以打补丁的方式增加了布尔类型。
使用布尔类型时需要包含stdbool.h头文件,才能使用 bool true false
字符型:字符就是符号或图案,但在计算机中是以整数存储的,当需要显示时会根据ASCII表中的对应关系显示出相应的符号或图案,也就是说字符就是使用整数模拟的。
'0' 48
'A' 65
'a' 97
总结:编程语言之所以把数据进行分类,是因为当使用合适的数据类型存储合适的数据可以提高代码的运行速度并节约内存,要了解各数据类型的特点、取值范围,在编程时选择合适的数据类型。
变量:
什么是变量:在程序运行过程中可以变量的量,用来存储数据的容器。
变量的定义:数据类型 变量名;
1、变量的默认值是随机的、不确定的,一些特殊用途的变量需要初始化,比如:求和、计数的。
2、变量的取名规则:
1、由字母、数字、下划线组成,不能使用特殊符号。
2、不能以数字开头。
3、不能与关键字(C语言中的32个关键字,要会默写)重名。
4、见名知意(功能+类型+使用范围)。
使用:
存储数据:变量名 = 1234;
参与运算:printf("%d\n",变量*3-2);
变量的输出:
C语言使用printf/scanf系列函数输入、输出变量的值,需要提供变量名字和类型,C语言使用占位符告诉printf/scanf变量的类型。
占位答:%c %hhu %hu %u %lu %llu %hhd %hd %d %ld %lld %f %lf %Lf
printf("提示信息+占位符+转义字符",变量名);
变量的输入:
scanf("占位符",变量的地址),&变量名 可以计算出变量的地址。
注意:现阶段scanf的双引号中,除占符什么都不要加。
常量:
常量就在程序运行过程中不能改变的量,C语言中的常量有:字面值常量、宏常量、枚举常量
'A' char 类型的字面值常量
100 int 类型的字面值常量
3.14 double 类型的字面值常量
100u unsigned int类型的字面值常量
100lu unsigned long类型的字面值常量
100llu unsigned long long类型的字面值常量
3.14f float 类型的字面值常量
3.14l long double 类型的字面值常量
格式化输出:
以下这种占位符的用法只是为了让数据显示的更整齐,了解即可。
%nd 数据至少显示n个字符宽度,不够则补空格,默认右对齐。
%-nd 数据至少显示n个字符宽度,不够则补空格,左对齐。
%0nd 数据至少显示n个字符宽度,不够则补0,右对齐。
%.mf 小数点后显示m位,不够则补0,多余的数据四舍五入。
%n.mf 小数点后显示m位,不够则补0,多余的数据四舍五入,数据至少显示n个字符宽度,不够则补空格,默认右对齐。
%-n.mf 小数点后显示m位,不够则补0,多余的数据四舍五入,数据至少显示n个字符宽度,不够则补空格,左对齐。
%0n.mf 小数点后显示m位,不够则补0,多余的数据四舍五入,数据至少显示n个字符宽度,不够则补0,右对齐。
%g 按实际情况显示小数点后的数据,不显示多余的0。
运算符:
算术运算符:+ - * / %
整型使用/运算时,结果会省略小数点,例如:2/3 得到的结果是0。
/ % 都是进行除法运算,/运算结果是商,%运算结果是余数,但它们的除数都不为0。
如果除以字面值0,编译器会有警告但不会报错,程序运行时会出现"浮点数例外,核心已经转储"错误,程序会提前结束不能再继续执行。
关系运算符:> < >= <= == !=
它们的运算结果是布尔值,但C语言中没有真正的布尔类型,所以使用0代表false,1代表true。
10 < num < 100 该表达式在数学中表示的是num的取值范围,但在C语言中它的运算结果永远为真,关系运算符的运算规则与数学中的不同。
在C言语表示num的取值范围:10 < num && num < 100
使用==运算符时,要把变量放在右边,常量放在左边,这样能防止少写一个=的情况:
100 == num; 100 = num; 这样编译器会报错
num == 100; num = 100; 这样就变成的赋值语句
逻辑运算符:&& || !
会先把运算对象转换成布尔值,0值转换成假,非0值转换成真,再进行计算。
A && B 一假即假
A || B 一真即真
!A 求反,它是单目运算符,比所有的双目运算符级别都高。
短路特性:当逻辑表达式的左边已经可以确定结果,右边的不再计算,合理的使用短路特性可以实现精简的if语句。
if(num > 100)
{
num = 0;
}
num > 100 && (num = 0);此代码与上面的if语句功能相同,但不建议使用,因为可读性比较低。
自变运算符:++/--
它们是单目运算符,运算对象必须是变量,可以让变量的值自动加1或减1。
前自变:++/--i 变量i的值会立即加1、减1。
后自变:i++/-- 变量的值不会立即变化,会在下一行代码执行前加1、减1。
三目运算符:[1] ? [2] : [3];
由于它的运算对象有三个,所以叫三目运行符,也是唯一的三目运算符。
首先把[1]部分转换成布尔值,为真执行[2],为假则执行[3],相当于精简的 if else 结构。
注意:三目运算符中不能使用 break、continue、return、goto 等语句,因为三目运算符构成的是表达式,必须有计算结果,所以不能中途跳转。
赋值运算符:= += *= /= ...
num += 10 <=> num = num + 10;
num /= 10 <=> num = num / 10;
字节运算符:sizeof
它不是函数,如果运算对象不是表达,它可以不使用小括号,它是C语言的32个关键字之一,用于计算数据类型在内存中占用的字节数。
注意:它不计算小括号中的表达式,只是推演一处运算结果是什么类型,然后计算出在内存中占用的字节数。
int num = 1234;
printf("%d\n",sizeof(num=6666));
printf("%d\n",num); // 执行结果是1234
printf("%d\n",sizeof(num>10:'A':3.14)); // 结果是8
位运算符:
该类型的运算符需要进制转换、原码、反码、补码方面的知识,后期再讲。
类型转换:
前提:只有相同类型的数据才能在一起运算,不同类型组成的表达式必须先转换成同一种类型(自动)再进行计算。
自动类型转换(隐式类型转换):
1、以不丢失数据为基础。
2、字节数少的向字节数多的转换。
3、有符号向无符号转换。
long num1 = -100;
unsigned long num2 = 33;
(num1+num2 > 0)? printf("大于零") : printf("小于零"); // 结果大于零
4、整型向浮点型转换。
5、char 和 short 会优先转换int类型再考虑是否需要继续转换。
short num1 = -100;
unsigned short num2 = 33;
printf("%d\n",sizeof(num1+num2)); // 结果是4
强制类型转换:
(目标类型)数据,会把数据强制转换成目标类型,但这种转换出的结果可能出现数据丢失,慎重使用。
if语句:
if(条件) // 单分支
{
// 条件为真时,执行此处代码
}
if(条件) // 双分支
{
// 条件为真时,执行此处代码
}
else
{
// 条件为假时,执行此处代码
}
if(条件1)
{
// 条件1为真时,执行此处代码
}
else if(条件2)
{
// 条件2为真时,执行此处代码
}
... 可以有多个 else if
else
{
// 上面的if条件都为假,执行此处代码
}
开关语句:
switch(整型数据)
{
case 数据1: 语句1; break;
case 数据2: 语句2; break;
case 数据3: 语句3; break;
...
default: 语句;
}
case 后面的数据必须是整型常量,它会与小括号中的的数据进行比较,如果相等则打开执行开关,开关打开后如果不关闭,接下来case后的语句都会执行。
break 语句可以关闭执行开关,如果每个case后都有一个break语句,那么就形成的多分支结构,break语句不是必须的,要不要加根据业务逻辑决定。
如果所有的case都不能匹配成功(都不相等),则default会打开执行开关,相当于多分支if最后的else。
gcc编译器特殊的switch用法:这不是通用语法,只有GNU系列的编译器才能使用。
switch(整型数据)
{
case start1 ... end1: 语句1; break;
case start2 ... end2: 语句2; break;
case start3 ... end3: 语句3; break;
default: 语句;
}