a) 安装位置剩余空间最少20G
b) 虚拟内存选择小于等于2G
c) 网络连接-----桥接
d) 虚拟磁盘类型IDE
e) 虚拟磁盘拆分成多文件、适中
a) 移除 autoinst.iso光驱、floppy(软盘)、打印机等
b) 添加串口Serial Port
c) 创建共享文件夹
【注】:(命令)linux rescue #用于系统修复
a) 检测安装介质、安装号码 -------跳过
b) 创建分区
类型 |
大小 |
作用 |
挂载点 |
|
swap |
内存2倍 |
虚拟内存 |
|
交换分区 |
ext3 |
100M |
引导分区 |
/boot |
|
ext3 |
剩余全部 |
根 |
/ |
|
c) 软件选择“软件开发”“网络服务”“现在定制”
d) 防火墙-----禁用
e) SELinux-----允许
键盘组合键:<Ctrl +Alt+Backspace> ------- 作用:重启X-windows
a. 挂载安装光盘
b.进入光盘目录 [root@localhost ~]# cd /media/
c. 将VMware Tools 解包到 /usr/local/src
tar –zxvf VMwaretools[tab][tab] –C /usr/local/src
d.执行安装脚本 *.pl
a.打开/etc/grub.conf
b. 在kernel行尾加入 vga=791
a.打开/etc/inittab
b. 将initdefault行中的5改为3
【注】修改完2、3文件后重启,系统将默认进入文本状态
Linux的运行级别
0 关机
1 单用户无需登录直接获得root权限(系统维护)
2 多用户、无网络(排除网络故障)
3 多用户、文本模式(系统、网络管理)
4 自定义
5 图形(桌面用户)
6 重启
在终端下执行 ntsysv
保留服务 |
haldaemon |
图形界面支持 |
kudzu |
即插既用设备 |
|
messagebus |
图形界面支持 |
|
network |
|
|
nfs |
nfs服务(网络文件系统可以将服务器上的目录共享给远程的计算机,并在远程计算机上挂载) |
|
protmap |
||
vmware-tools |
|
|
vmware-tal。。。。 |
|
|
xfs |
超级服务器---可以管理很多不能独立运行的网络服务 |
|
xineted |
|
目录 |
作用 |
备注 |
/ |
boot |
Linux内核、引导程序(grub、lilo) |
内核的作用: 文件管理、内存管理、进程管理、设备管理 |
bin |
普通用户可以执行的命令 |
|
|
sbin |
只有超级用户可以执行的命令 |
|
|
etc |
配置文件目录 |
|
|
/etc/rc* |
rc表示Runlevel Changes(运行级别) |
||
proc |
内核启动映像 |
观察内核的运行状态、微调内核的一些参数 |
|
sys |
系统总线映射 |
|
|
usr |
第三方软件目录 |
/usr/include C头文件 |
|
root |
超级用户专属目录 |
|
|
home |
普通用户家目录 |
|
|
media |
光盘挂载目录 |
|
|
mnt |
外部存储设备挂载目录 |
|
|
tmp |
临时文件目录 |
|
|
var |
日志(网站)等需要频繁访问的文件 |
|
|
lib |
C库目录 |
|
|
dev |
设备文件目录 |
每个文件对应一个设备,而设备可能存在,也可能不存在 |
|
/dev/ttyn |
物理终端 |
||
/dev/ptsn |
虚拟终端 |
||
/dev/zero |
只读 ——0 |
||
/dev/null |
只写 ——丢弃 |
||
/dev/random |
只读 ——随机数 |
||
/dev/console |
操作系统所必须,关系到系统登录 |
1. <Alt+Fn> n=1~7 ——物理终端间切换
2. 文本下启动图形界面 startx
3. 退出图形界面 <Ctrl+Alt+Backspace>
4. 图形界面下运行文本<Ctrl+Alt+Fn> n=1~6
5. 文本进入图形 <Alt+F7>
6. 终止程序运行 <Ctrl+C>
7. 执行程序运行命令时,在末尾家&——表示让程序在后台运行
8. 作业调度
jobs #查看作业号
fg 作业号 #将后台作业调入前台
<Ctrl+Z> 表示挂起前台作业
bg 作业号 #将挂起作业调入后台
9. <Ctrl+L> 清屏
10. history #显示历史命令 默认最多1500条
11. ! 历史命令编号 #重新执行该命令
12. 历史相似命令
a. <Ctrl+r> 注:在宿主机即虚拟机外将重启虚拟机
b.输入相似部分
c. 回车执行
13. Tab用法
a. 补全命令
b.显示相似命令
c. 补全目录或文件
只能写标准输出中输出的字符串
可以写任意文件中输出的字符串
【注】在Linux中一切皆文件
a. stdin ——标准输入
b.stdout ——标准输出
将数据存入缓冲区,待缓冲区满或遇到换行字符或程序结束时,才向输出设备上输出内容
c. stderr ——标准错误输出(不经过缓冲区直接输出)
例:fprintf(stdout, “Hello”);
a. return EXIT_SUCCESS;
EXIT_SUCCESS宏定义在stdlib.h文件中,宏值为0,表示程序运行成功并退出
b.return EXIT_FAILURE;
EXIT_FAILURE宏定义在stdlib.h文件中,宏值为1,表示程序运行失败,并退出
注:返回值使用宏定义目的在于提高程序的可读性,在main中使用也可以在调用exit函数中使用。
void exit(int status)结束当前进程,status形参的值用于程序退出的值,相当于main函数中的return值
assert(0) //如果形参的值为真时,不做任何处理;否则退出程序,并报错
例:
运行结果:
[root@localhost ~]# gcc a.c
/tmp/cc37WP4H.o: In function `fun':
a.c:(.text+0x1b): undefined reference to `assert'
collect2: ld 返回 1
例2:
1.
reboot
2. shutdown -r now 重启
3. init 6
4.
shutdown -h 0
5. poweroff 关机
6. init 3
7.
logout
8. exit 退出登录(终端下)
功能:显示当前工作目录的绝对路径
功能:显示文件和目录列表
语法:ls [参数列表] [文件或目录名称列表]
参数: -a 显示所有文件包括隐藏文件(文件名以.开始的文件)
-l 以长格式显示文件完整信息
-h 以适当单位显示文件大小(必须与-l配合)
-R 递归显示目录中的所有文件
-i 显示文件的i节点的值
节点:每个文件系统会对磁盘上的文件进行编号,这个号码在当前文件系统中是唯一的
【注】中括号——可选项
尖括号——必选
列表用空格分隔,不特殊说明,次序不限
【附】提示符:$PS1 用于定义shell提示符,显示内容与颜色
例:echo $PS1
\u : 当前用户
\h : 当前主机
\w:
当前工作目录 # 超级用户
\$ : 提示符类型
$ 普通用户
\A:24小时格式显示HH:MM
我的设置:
PS1="\[\e[36m\]\A
\[\e[32m\][\u\[\e[31m\]@\[\e[33m\]\h \[\e[32m\]\W]\
\[\e[31m\]\$\[\e[0m\]"
命令过长时用于换行
显示效果:
ls长格式显示说明:
第一列:文件权限及类型说明
1 |
2 3 4 |
5 6 7 |
8 9 10 |
文件类型 所有者权限 所属者权限 其他人权限
[ - 普通文件
d 目录
l 符号链接(软链接)
p 管道文件
c 字符设备文件——顺序读写
b 块设备文件——随机读写(意义:统一设备访问接口,除特殊设备(网卡))
s 套接字文件
文件颜色
黑色——普通文件 蓝——目录 黄——设备 浅蓝——符号链接
红——压缩文件 绿——可执行文件 红闪——丢失目标的符号链接
紫——套接字 棕——管道文件
第二列:硬连接数(一个文件有几个文件名,而它的i节点号相同)
第三、四列:文件大小(空目录大小4096)
注:设备文件表示主次设备号,设备号相同,表示使用相同的驱动程序,次设备号,表示不同的子设备
第五列:文件时间 ctime 创建时间
atime 最后访问
mtime 最后修改
注:alias ll=’ls -l’ (临时修改命令别名)
功能:改变工作目录
语法:cd [目标目录]
示例:cd - (回到上一次所在工作目录)
功能:创建目录
语法:mkdir [参数] [目录列表]
参数:-p 递归创建
功能:修改文件时间或创建一个空文件
语法:touch [文件列表]
注:如果文件存在用来修改或目录的时间(当前系统时间),否则创建一
空的普通文件
功能:删除文件或目录
语法:rm [参数] [文件或目录列表]
参数: -r 删除目录时加此参数
-i 每删除一个文件或目录时提醒
-f 删除前不提醒
注:rm命令默认情况下,不提示,直接删除,所以在很多操作系统上位rm
命令起别名:alias rm=’rm -i’
功能:文件目录移动或更目
语法:mv [参数] 源文件或目录 目标文件或目录
参数:-f 覆盖前不提醒(强制删除force)
注:目标文件或目录,存在——移动;不存在——更名
功能:复制文件或目录
语法:cp [参数] 源文件或目录列表 目标文件或目录
参数: -r 复制目录,默认只复制文件不复制目录
-f 覆盖前不提醒
-a 不改变文件的权限和属性
注:如果文件已存在,覆盖时保持原有权限属性不变
功能:创建链接文件
语法:ln [参数] 源文件或目录 链接文件名
参数:-s 创建软连接(符号链接)文件
注:默认情况下。ln创建硬连接文件
功能:查看文件
语法:cat [参数] 文件名
参数: -n 显示行号
-b 空行不显示行号
-s 连续多个空行,只显示一个空行
功能:分页显示文件
用空格翻页,q退出
功能:同more
用<pageup/down>翻页,q退出
功能:显示文件尾部内容
语法:tail [-n 行号] 文件名
功能:显示文件首部内容,使用同tail
功能:文件查找
语法:find 起始路径 -name 文件名 [-ls]
说明:基于文件名查找,[-ls]用于长格式显示查找结果
注:文件名中可以使用通配符
*可以通配任意个任意字符
?可以通配一个任意字符
功能:基于文件内容查找
语法:grep [参数] 查找内容 起始路径或文件名
参数: -n 显示行号
-r 递归查找
-i 忽略大小写
功能:基于数据库进行查找
语法: 创建数据库(整个磁盘文件名数据库) updated
查找 locate 部分或全部文件名
注:在更新数据库后的文件改变无法查找
功能:命令或命令别名查找
语法:which 命令或命令别名
功能:添加组
语法:group 组名 [-g 组ID]
注:系统会为用户和组进行编号,小于500的为系统用户或系统组,默认情
况下新添加的组和用户的ID由500开始
功能:添加用户
语法:useradd [-g 组名] [-d 家目录] 用户名
参数: -g——省略
i. 先创建与用户名相同的组
ii. 创建用户并添加到此组
-d——省略 创建家目录 /home/用户名
功能:删除用户
语法:userdel [-d] 用户名
参数:-d 删除用户的同时删除其家目录
功能:删除组
语法:group 组名
注:必须是空组才能删除
功能:修改用户密码
语法:passwd [用户名]
注:不加用户名,修改当前用户密码;否则,修改指定用户密码,但仅限超级用户
功能:用于切换用户
语法:切换 su [-] [目标用户]
参数: - ——不写,只切换用户不改变环境设置
省略目标用户——相当于root
示例: su
linfeng ——$PATH (root)
root su - linfeng ——$PATH(linfeng)
返回原用户 exit
功能:改变文件所属组
语法:chgrp 组名 文件或目录名列表 [参数]
参数:-R 递归修改
功能:改变文件或目录的所有者和所属组
语法:chown [参数] 所有者.所属组 文件或目录列表
参数:-R
说明: 所有者 —— 只修改所有者
所有者.所属组 —— 两者都修改
.所属组 —— 只修改所属组
示例:chown -R linfeng.embedded a.c
功能:改变文件权限
语法:chmod [参数] 权限表达式 文件或目录列表
参数:-R
权限表达式:
i. 八进制 r w x
4 2 1
ii. 组合表达
所有者 |
u |
+
- = |
r |
所属组 |
g |
w |
|
其他人 |
r |
x |
|
以上三组 |
a |
|
示例: chmod u+x test #给test文件所有者执行权限
chmod ug+rw test
附:
etc/passwd #该文件存储用户的配置信息
etc/group #该文件存储用户组配置信息
功能: (1)分区管理
fdisk 磁盘设备文件名
示例:fdisk /dev/sda #对/dev/sda磁盘进行分区
(2)磁盘设备查看
fdisk -l
功能:磁盘设备挂载
语法:mount [-t 分类类型] [-o 挂载参数列表] 设备文件名 挂载点
分区类型:
类型 |
用途 |
备注 |
vfat |
Win下fat和fat32 |
通常可省略参数 -t |
ext3 |
Linux |
|
iso9660 |
光盘 |
|
smbfs |
Win下网络邻居共享目录,Linux对应samba文件系统 |
|
nfs |
Network file system |
|
yaffs |
嵌入式设备,可读写文件系统 |
|
ntfs |
Win下ntfs |
|
挂载参数: ro 只读
rw 读写
gid 指定挂载点组ID
uid 指定挂载点用户ID
mode=xxx 指定挂载点权限
iocharset=cp936 (字符设备乱码问题)
注:在UNIX族操作系统上,将存储设备与目录进行关联的操作称为挂载,被关联的目录称为挂载点。
功能:卸载
语法:umount 挂载点或设备文件名
注:device a busy 的原因 —— 此设备正在使用
功能:文件系统查看
语法:df [参数] [分区设备文件名或挂载点]
参数:-h 以适当单位显示大小
示例:df -h /dev/sda1
功能:查看目录使用情况
语法:du [参数] [目录名]
参数: -s 只显示总计使用情况
-h 同上
示例:du -sh /mnt/usb
功能:查看系统环境变量
变量格式: 变量=值
常见变量:
HOSTNAME |
当前主机名 |
SHELL |
当前shell |
HISTSIZE |
历史命令记录数量 |
USER |
当前用户名 |
LS_COLORS |
指定ls显示不同文件的颜色 |
PATH |
命令路径 |
PWD |
当前路径 |
LANG |
当前语言类型 |
HOME |
家目录 |
LOGNAME |
登录用户名 |
OLDPWD |
上一次所在工作目录 |
功能:查看和修改系统时间
语法: (1)查看 date
(2)修改 date MMDDHHmm[[cc]YY][.SS]
月 日 时 分 年 秒
功能:查看和修改rtc时钟
语法: (1)查看 hwclock
(2)修改 hwclock -s (以rtc时钟同步系统时钟)
hwclock -h (以系统时钟修改rtc时钟)
功能:IP查看与设置
语法: (1)查看 ifconfig [网卡设备名]
(2)配置 ifconfig 网卡设备名 IP地址 [netmask(子网掩码)]
注:网卡名 eth m[n]
m ——物理网卡ID
n ——虚拟网卡编号(一个网卡最多虚拟四个网卡)
功能:打包或解包
语法: 1)打包 tar zcvfj 包文件名 目录
参数: z gzip压缩
c 创建包(必选)
v 显示打包过程(可选)
f 打包成文件(必选)
j bizip压缩
压缩类型比较:
类型 |
压缩比 |
速度 |
扩展名 |
bizip |
大 |
慢 |
.tar .bz2 |
gzip |
小 |
快 |
.tar .gt或.tgz . |
2)解包 tar zxvf 包文件名 [-C 目标目录]
参数: x 解包
-C 指定解包路径
3)查看包 tar ztvf 包文件名
功能:红帽包管理
用法: 1)安装包
rpm -ivhU --nodeps rpm包文件名
参数: -i 安装(install)
-v 显示安装过程
-h 显示安装进度
-U 若包已安装则更新
--nodeps 不检查依赖关系直接安装
2)查看系统已安装了哪些rpm包
rpm -qa
3)卸载rpm包
rpm -e 包名
4)查看已安装文件
rpm -ql 包名
技:“|”管道符
cmd1 | cmd2 —— cmd1的标准输出将为cmd2的标准输入
创建以下目录结构满足学习需要
/work/
|-- C
|-- C++
|-- database
|-- embedded
| |-- bootloader
| |-- filesystem
| |-- kernel
| |-- qt
| `-- toolchains
|-- process
|-- project
|-- qt
|-- shell
|-- signall
|-- socket
| |-- tcp
| | |-- client
| | `-- server
| `-- udp
|-- software
`-- systemcall
|-- base
|-- jpegdisplay
`-- waveplay
遇到问题根据提示解决进行分析
1)在哪里产生
2)为什么产生
3)解决方案
4)解决问题(能备份一定要备份,数据无价)
功能:查看进程
语法:ps [参数]
参数: a 显示所有终端进程
u 显示进程详细信息
x 显示系统进程
示例:ps aux
每列意义: USER 进程拥有者
PID 进程号
注:进程号范围1~65535,每个进程加1,循环递增使用
进程ID为1的进程为init进程是系统第一个进程,又称为初始进程,是所有进程的“父”进程,在系统运行过程中其一直驻留内存
%CPU
%MEM 内存占用率
VSZ 虚拟内存大小
RSS 物理内存大小
? 不依赖任何终端
TTY 进程所依赖的终端 ttyn 占用终端
ptsn 虚拟终端
注:在Linux中所有设备个数标号几乎都从0开始,因此tty2将表示第三个终端
S 休眠
STAT 进程运行状态—— R 运行中
START 启动时间 Z 僵尸进程
TIME 运行时间(实际占用处理器的时间)
COMMAND 启动命令
注:pstree //进程树—以树的方式显示进程说明之间的关系
功能:动态进程查看
语法:top
命令: m 显示内存统计信息
q 退出
功能:显示内存信息
语法:free [参数]
参数: -g
-m
-k
-b
注:基本单位,默认以k为单位
功能:给指定进程发送指定信号
语法1:查看信号列表
kill -l
SIGUP |
挂起 |
SIGINT |
终端中断信号 |
SIGAPRT |
程序异常终止 |
SIGFPE |
浮点数例外 |
SIGKILL |
进程终止 |
SIGSEGV |
段错误(内存非法访问,win下蓝屏) |
语法2:为进程发送信号
kill -信号值 进程ID
注:信号——在Linux操作系统上用于实现进程间的简单通信
功能:结束进程(基于进程启动命令)
语法:killall 进程启动命令
示例:killall httpd #daemon进程守护
注:内部实际发送的信号为SIGKILL
注:httpd网站服务器程序,IIS,apache(阿帕奇)
Vi [文件名称] [+行号]
:wq 保存并退出
:q 退出
:q! 不保存退出(强制退出)
:w 保存
:w 文件名 另存为
:w! 强制保存
编辑模式 :功能等同于记事本
Ii,Aa,Oo,Ss
<ESC>
命令模式 :对vi下达简单编辑命令(默认)
<ESC>
:或/
末行模式 :下达文件操作命令或查找、另存为等相对复杂的操作命令
插入 I 。。。。。行首
I 插入到当前光标前
追加 A 。。。。。行尾
a 追加到当前光标后
新行 O 。。。。。。。上。。。。。
o 在当前行下新建一行
替换 S 。。。。。。。行
s 替换当前字符
复制 [n]yy 复制n行,复制一行时可省略n
剪切 [n]dd 剪切n行,剪切一行时可省略n
粘贴 p 将剪切板内容粘贴到当前行下(可视情况除外)
撤销 u 撤销编辑操作
恢复 :redo 恢复已经撤销的操作
<pageUp> <pageDown>
h j k l <home> <end>
W 下一字符首(白空格——空格、制表符、换行)
w 下一单词首(白空格,字符类型不同划分单词)
E 下一字符串尾
e 下一单词尾
gg 文件首
G 文件尾
:行号 调到第几行
1) 将光标移动到要查找的单词上
2) 按“#”
3) 大写“N”下一处
小写“n”上一处
1) /字符串
2) 大写“N”下一处
小写“n”上一处
:%s/原串/新串[/g] #g表示全局替换
水平分屏 :split 文件名
垂直分屏 :vs 文件名
<Ctrl+w> . W 下一屏
<Ctrl+w> . W 上一屏
主要用于非整行的复制、粘贴、剪切操作
1. 将光标移动到可视的开始或结束处,按“v”
2. 通过光标移动命令将光标移动到可视的结束或开始处
3. 通过“d”剪切、“y”复制
4. 通过“p”可将剪切或复制的可视内容粘贴到光标后
行号 :set nu
:set nonu
语法加亮 :syntax on
:syntax off
去除查找内容加亮 :nohlsearch
设置水平制表符缩进 :set ts=n #n为缩进量
永久配置
i. 修改~/.bashrc #加入vi=’vim’的别名命令
ii. 编辑vi配置脚本
~/.vimrc
加载引导程序
作用:加载操作系统内核,负责向内核传递启动参数
种类:pc grub 嵌入式设备 vivi 小
lilo
u-boot
加载内核
配置文件:
/etc/grub.conf(/boot/grub/grub.conf)
![]() |
挂载存储设备
—— /etc/inittab
![]() |
—— /etc/fstab
![]() |
/etc/sysconfig/network
网络配置
/etc/sysconfig/network-scripts/ifcfg-xxx
/etc/resolv.conf
/etc/hosts
/etc/profile #用户环境(与bash无关)
~/.bashrc #用户环境设置
用户配置
/etc/bashrc #用户环境(针对bash shell)
/etc/passwd #用户设置
/etc/group #组设置
/etc/shadow #密码设置
a. 全局变量(顶格)
default=值 #用于指定默认引导的操作系统(由title次序决定其值)
timeoutout=值 #默认引导超时时间
splashimage=(hd0,0)/grub/splash.xpm.gz #背景图
#个性制作——320*480 索引图——保存xpm格式——gzip压缩
#(hd0,0)表示第一块硬盘的第一分区,相当于/boot/
Hiddenmenu #隐藏操作系统菜单选项
title #菜单项文件
password=xxxxx #MD5密码(128位)
b. 局部变量(一个制表符)
root 用于指定引导分区(内核所在分区,即/boot文件系统)
kernel /vmlinuz-2.6.18-308.el5
ro root=LABEL=/ rhgb quiet vga=791
#用于指定内核引导参数
1.内核所在文件2.以只读方式挂载根分区
3.用于指定根文件系统的位置[标签](等同于root=/dev/hda3)
4.启动时不打印任何信息
5.用于指定终端显示模式
vga——frame buffer 模式(以内存作显存,可不用显卡)
vga设置代表开启帧缓存模式(解决找不到fb设备文件)
791——十六进制表示1024*768*16bpps(16表示十六位色,屏幕上一点,占两个字节用来放三原色,rgb565)
5r |
6g |
5b |
initrd #系统启动镜像文件
chainloader +1 #工具链
注:
注:生成MD5密码命令
[root@linfeng ~]# grub-md5-crypt
![]() |
格式: 标号:运行级别:动作:命令
1. 自定义(2~3个字符)
2. 0~6之间,0项或多项,表示此配置项在哪个初始化级别下生效,不写表示所有级别均生效
initdefault #指定系统默认初始级别
3. 默认 sysinit #指定系统初始化脚本(系统参数、环境变量)
wait #等待该项执行完毕后,再执行其他配置项
格式:
设备文件名 挂载点 文件系统 挂载参数 开机是否磁盘检测
挂载次序
前四项参考mount 1——检测
0——不检查
由1~n逐次挂载。0最后挂载,
注:如果在文件中出现的存储设备,挂载时仅需指定设备文件或挂载点即可。
例如:fatab中有一行
/dev/cdrom /media iso9660 defualts 0 0
挂载此设备时,仅需执行 mount /dev/cdrom
mount /media
NETWORKING=yes/no #系统启动时是否开启IPV4网络支持
HOSTNAME=xx.xx.com #当前主机名称(全名)
GATEWAY=xx.xx.xx.xx #网关IP
注:网络是否启动与网关地址配置,重启网络后生效
主机名配置重启系统后生效
重启网络方法:
service network restart
Linux下服务管理命令 start
服务名 stop
(见ntsysv) status #状态
DEVICE=xxx #设备名等同于(完全相同)
BOOTPROTO=static/dhcp #静态设置或动态获取
BROADCAST=xxxx #广播地址
HWADDR=xxxx #MAC地址一般不能改动(可以没有,但不能错)
IPADDR=xxxx #IP地址
NETMASK=xxxx #子网掩码
NETWORK=xxxx #网络
ONBOOT=yes/no #网卡是否随网络启动(no——禁用网卡)
我的配置文件如:
1 # Advanced Micro Devices [AMD] 79c970 [PCnet32 LANCE]
2 DEVICE=eth0
3 #BOOTPROTO=dhcp
4 BOOTPROTO=static
5 HWADDR=00:0C:29:0D:C8:92
6 BROADCAST=192.168.11.255
7 IPADDR=192.168.11.11
8 NETMASK=255.255.255.0
9 NETWORK=192.168.11.0
10 ONBOOT=yes
11 #IPV6INIT=yes
12 #IPV6_AUTOCONF=yes
13 #GATEWAY=192.168.11.255
14 #TYPE=Ethernet
注:网卡重启配置生效
重启网卡 ifdown 网卡设备
Ifup 网卡设备
可能出现错误:错误:激活连接失败:Device not managed by NetworkManager
解决方法:关闭NetworkManager服务
# service NetworkManager stop
为防止下次重启时,该服务重新启动而使网卡重启失败
# chkconfig NetworkManager off
DNS客户端设置——(作用是主机名转为IP地址)
search xxxxx #没用可以删除
nameserver DNS服务器IP #(最多三个)
主机表文件——主要负责本机IP与主机名解析与反解析
(不添加主机表,可能导致图形界面起不来或启动缓慢)
用户环境——所有用户均执行此文件,重新登录生效(Bash无关)
用户环境设置——只针对当前用户有效,重新登录后生效
用户环境设置——针对所有用户,重新登录后生效(针对Bash shell设置)
用户设置——格式
用户名:是否需要登录密码:用户ID:组ID:用户说明:家目录:用户shell
X-需要 空-不需要
注:修改后立即生效
组设置——格式:
组名:组密码:组ID:组扩展用户列表用“,”分隔
有无无所谓
密码设置——格式:
用户名:MD5密码:。。。。。。。。。。
开机后进入单用户系统
1. 按“e”进入编辑模式
2. 修改内核参数,在最后加1(即可进入单用户)
<Ctrl+d> 结束单用户
取消Tab键报警声
进入/etc/inputrc
删除set bell-style none 行前面的注释符#
彻底消除报警声
修改/etc/rc.d/rc.local文件(脚本文件),在最后面加上一句rmmod pcspkr命令(目的是让系统每次在开机的时候删除pcspkr内核模块)
重启
rmmod
功能说明:删除模块。
语 法:rmmod [-as][模块名称...]
补充说明:执行rmmod指令,可删除不需要的模块。Linux操作系统的核心具有模块化的特性,应此在编译核心时,务须把全部的功能都放如核心。你可以将这些功能编译成一个个单独的模块,待有需要时再分别载入它们。
参 数:
-a 删除所有目前不需要的模块。
-s 把信息输出至syslog常驻服务,而非终端机界面。
与内核模块操作相关的命令还有
:lsmod modinfo depmod rmmod inmod modprobe
pcspkr内核模块
Shell:用于用户与内核进行交互的一段程序
分类: 1)GUI 用户图形接口
2)CUI 终端用户接口
[ ash —— 嵌入式设备(小)
[ bash —— pc机(全)
[ csh —— 网络设备(网)
1) 命令
2) 变量
3) 注释(只有单行注释,以#号开始,至行尾结束)
4) 解释器说明
#!解释器路径
#!/bin/sh——符号链接,用于指定当前系统使用的默认shell
注:嵌入式系统中的应用
a) 系统的环境设置
b) 启动或配置应用
c) 设备的加载与参数设置
Shell脚本默认扩展名为.sh
echo #显示字符串、变量
参数:-n 不换行显示
1) 使用当前shell解释执行
语法: source 脚本文件名(可包含相对或绝对路径)
. 脚本文件名(可包含相对或绝对路径)
2) 使用指定shell解释执行
语法: shell命令 脚本文件名
示例: sh test.sh
3) 直接运行(脚本中指定shell执行)
语法: 路径/脚本文件名
示例: ./test.sh
三种形式变量:
a) 系统变量:由操作系统设置(env)
b) 预定义变量:
$? —— 上一条命令的执行结果(任何命令执行成功返回0,执行失败返回非0,而非0值一般为错误号)
$0~$9 —— shell脚本执行时的命令行参数
例:./test.sh [参数列表(空格分隔)] #实际使用$1~$9,$0代表自身
c) 自定义变量:
i. 变量无类型
ii. 无需声明
语法:
i.
赋值 变量名大写,单词下划线连接
规定: 等号两端不能有空格
值中包含空格要使用引号括起来
ii. 引用:$A
iii. 释放:unset A B C (变量列表空格分隔)
注: ‘单引号’不支持变量,”双引号”支持变量
`反引号`用于括起来一条shell命令,当执行到包含反引号的语句时,当先执行反引号中的命令
1) 文件测试
语法:test 测试符 文件名/目录
[ 测试符 文件名/目录 ]
测试符: -r 读
-w 写
-x 执行
-d 目录
-f 文件
-L 符号链接
-e 存在
2) 数值测试
语法:test 数值1 测试符 数值2
[ 数值1 测试符 数值2 ]
测试符: e 等于
n 不等于
l 小于
g 大于
t、q 无意义
示例: -lt -le -nl -eq -ge
3) 字符串测试
语法1:test 串1 测试符 串2
[ 串1 测试符 串2 ]
测试符: == !=
注:测试中一旦出现变量要用双引号将其括起来,否则可能出错
语法2:test 测试符 串
[ 测试符 串 ]
测试符: -n 是否非空
-z
4) 逻辑测试
-a and 与
-o or 或
! 非
5) 算数运算
语法:expr 操作数1 运算符 操作数2
运算符:+ - * /
(运算符两边加空格,乘法需要使用转义\*)
6) 特殊符号
? * 通配符
` ` 反引号
\ 转义符
|
模式 |
符号 |
说明 |
输入重定向 |
新建 |
< |
将符号后内容定向到符号前命令的stdin |
追加 |
<< |
|
|
输出重定向 |
新建 |
> |
将符号前命令的stdout定向到符号后的文件 |
追加 |
>> |
(不清空原有内容) |
语法: 输入重定向 cmd < 串
输出重定向 cmd > 文件
注:标准错误输出,是将stderr定向到stdout然后输出(2>&1)
stdin 0
stdout 1
stderr 2
例: ls adsadas >>test 2>&1
ls adsadsa >>/dev/null 2>&1
从命令行读取数据
语法:read 变量名
1) 分支(if)
if 测试1
then
命令1
elif
测试2
then 可重复,0~任意次
命令2
else 可选
命令3
fi
2)
分支(case)
case $变量 in 数值) 5)
模式1) #模式用于设置匹配方式 字符串) stop)
命令 正则表达式) 9[0-9])
;;
模式2)
命令
;;
模式n)
命令
;;
esac
3) 循环(while)
while 测试 #真值时循环
do
命令
done
until 测试 #假值时循环
do
命令
done
4) 循环(for)
for 变量名 in 值列表(空格分隔)
do
命令
done
用法:
定义: function 函数名
{
#函数体
}
调用: 函数名 参数列表
注:参数列表与命令行参数用法一样,$0~$9
函数在shell当中相当于一条命令
1. 命名法:
匈牙利法:字母全小写,单词以下划线分隔
骆驼法:函数——每个单词首字母大写
变量——第二个单词开始首字母大写
2. exit 1 #退出当前shell
3. 目录的可执行权限
表示是否可以进入这个目录,软连接文件的权限都是777
源文件
静态库 共享库
预处理 编译 组译 链接
预处理
1) #include 头文件包含
2) #define PI 3.14 宏替换
3) #ifdef 条件编译
#if 0
等预处理
静态库:编译时加载,运行时无关
共享库:编译时检测,运行时加载
gcc [参数] [源文件列表]
Gcc 默认编译到链接阶段,生成可执行文件
-E 仅编译到预处理阶段,将预处理后的代码作为stdout
-S 进行到编译阶段,生成同名的.s汇编文件
-c 进行到组译阶段,生成同名的.o目标文件
-o 文件名 用于指定编译器输出文件时的文件名
注:编译器自带宏 __FILE__, __FUNCTION__, __LINE__
表示 当前文件 所在函数 当前行号
-I路径 用于为当前预编译添加默认头文件(需要用到的头文件不在默认目录时)
例:gcc main.c -o main -I. #包含头文件在当前目录
-include 头文件 用于指定当前预处理包含的头文件(需要调用的头文件不在该文件中时)
例:gcc main.c -include def.h #文件中需要引用def.h头文件
-D宏名 用于向当前预处理添加宏定义
例:gcc main.c -DSUMMER #给文件一个宏参数
(宏相关见C语言)
-l库名 指定链接库
例:./sin -lm #math.h头文件需要调用链接库 (见man sin)
注:C库名称规范
libxxx.so.版本号 —— 共享库
libxxx.a.版本号 —— 静态库
lib.xxx.la.版本号
前缀 库名 类型
-L路径 添加链接库默认路径
-static 使用静态链接库
-s 去除冗余 —— 如标识符(见nm)
-On n为0~4的整数,用于指定编译器对代码的优化级别,数值越大优化级别越高(-O0 为默认)
注:优化是编译器修改变量的存储位置与流程控制
建议:优化级别为2或3
-Wall 显示所有警告信息
建议编译参数:-Wall -O3 -o 文件名
语法: gcc -fpic -shared
源文件列表
-o 库文件名
地址可重定位 共享库
示例: gcc -Wall -O3 -fpic -shared *.c -o libxxx.so
使用: gcc -Wall -O3 -s main.c -o main -L. –I.
共享库运行时不能加载解决方法:
方法1:添加到共享库默认路径为/lib/(针对于自己制作的共享库不提倡)
方法2:通过环境变量指定共享库位置
LD_LIBARAY_PATH变量末尾加上自己的“:库路径”
方法3:
a. 修改Linux配置文件/etc/ld.so.conf,在此文件中新起一行写上库路径
b. 执行命令ldconfig,更新系统共享库的hash表
1. 将要制作的静态库的源文件编译成目标文件
2. 归档(archive)
ar -r 静态库名 目标文件列表
3. 编译 略(参照共享库)
4. 运行 略
1. ldd ——查看可执行文件运行时所需要的共享库
用法:ldd 可执行文件名
2. file ——查看文件类型、架构等信息
用法:file 文件名
3. stat ——查看文件属性、权限、时间等信息
用法:stat 文件名
4. nm ——查看可执行文件中的标识符(包括库文件)
用法:nm 可执行文件名 #strip的文件无效(gcc参数-s)
5. strip ——去除可执行文件中的冗余信息(包括库文件)
用法:strip 可执行文件
6. cproto ——由.c源文件生成.h头文件
用法:cproto 源文件名 #重定向到所需的.h文件中
1. 错误提示中由行号、文件、函数名是编译时出错,语法错误
2. 不显示行号等信息,链接错误
1. ftp 服务器IP或主机名 #进入ftp登录会话
2. 输入用户名、密码
匿名用户,用户名:ftp 密码:无(直接回车)
成功后进入ftp shell
操作命令:
ls 查看服务器文件列表
cd 切换在服务器中的目录
get 服务器上的文件名 下载一个文件
put 本地文件名 上传一个文件
mget 服务器上的文件名(可带通配符) 下载多个文件
mput 本地文件名(可带通配符) 上传多个文件
by 退出ftp shell
3. 保存位置为当前打开ftp的目录
1. 解包到指定目录(/usr/local/src/)
2. 进入源码目录
3. 对源码软件进行配置
配置方法:(执行配置脚本)
./configure [--help] #不加参数默认安装
注:为什么要配置?
a. 检测系统架构
b. 检查库是否满足条件
c. 检测编译器版本
d. 生成编译规则文件
4. 编译 make
5. 安装 make install
注:默认情况下,手动源码安装的库文件,在/usr/local/lib/目录下
1. 多个源文件和头文件构成的项目,要为其创建一个目录,项目目录。该项目名应对应项目的可执行文件名
2. #include < >(中间加空格)
3. 运算符两侧必须加空格,一元运算符除外。
4. 逗号后加空格。
5. 声明语句和可执行语句之间加空格
6. return 之前加空格
7. 一条语句过长时,要分多行书写
8. 用水平制表符进行缩进,缩进要按层次,制表符宽度为4(set ts=4)
9. 文件末尾加空行
10. 在程序编译过程中,如果找不到一些函数的声明,在主函数中进行声明时,若该函数是主函数外的文件中,通常在所声明函数前加extern
如:extern void fun();
11. 在函数命名时通常采用见名知意,因此在应用别人的函数或库时,有init函数名的函数中,可能会有申请内存的操作。同时会在destory/close函数名的函数中会释放。
12.
主要针对内存,为了节省内存
整型 |
char |
1 |
Unsigned值域0~255 |
Signed值域-128~127 |
|||
short |
2 |
Unsigned值域0~65535 |
|
Signed值域-32768~32767 |
|||
int |
2 |
字节数-16位系统以下 |
|
4 |
字节数-32位系统以上 |
||
long |
4 |
以1开头的10位整数 |
|
long long |
8 |
(4+4 = 8) |
|
short long |
3 |
((2+4)\ 2 =3) |
|
实型 |
float |
4 |
(精度)小数点后6位 |
double |
8 |
(精度)小数点后16位 |
值域范围: n = 字节数 * 8
无符号 0 ~ 2^n – 1
unsigned int
有符号 -2^(n-1) ~ 2^(n-1) – 1 int
常量表示法:
5 |
5L |
5.0 |
5.0f |
.5 |
075 |
0x123f |
0UL |
|||
int |
long |
double |
float |
double |
八进制int |
十六进制int |
0 unsigned long |
|||
2E3 |
-2E-3 |
0.8E-5 |
.8E-5 |
8E0.5 |
|
|
|
|||
2*10^3 |
-2*10^-3 |
都double |
||||||||
‘a’ |
‘\n’ |
‘\m’ |
‘\0’ |
‘\123’ |
‘\x1234’ |
|||||
字符a |
换行 |
m |
0 |
字符的八进制表示法(转义字符开始不多于3位的八进制数) |
字符的十六进制表示法(转义字符+x开始后不多于4位的十六进制数) |
|||||
i. 数组
声明:类型 数组名 [行长度][列长度]={{…}, {…}, ….{…}}
在内存中按行存储
ii. 指针
声明:类型 *变量名
存储内存地址的变量,为了存储所有地址,所占字节数与该系统的地址总线有关。一般与int类型的字节数相同。
指针的运算:
指针与整型 p + n p – n
如:p + 1 —— 指向下一个元素(元素表示给指针的类型单元)
Int *P = (int *)0x1000 0000;
P + 2;
所以此时P为0x1000 0008
指针与指针 p – q
指针与指针进行减法(两指针类型必须相同),只有两指针指向同一数组时,才有意义,其运算结果为两指针间有多少个元素。
iii. 枚举
enum 枚举类型 {枚举列表}
例:enum WEEK{Monday = 5, Tuesday, 。。。。}
1. 结构体
i. 先定义类型
ii. 通过定义的类型声明变量
iii. 结构体取成员的运算符有两个,分别是 . 和 ->
. 是通过结构体变量取成员 如:s.a;
->是通过结构体地址取成员 如:ps->a;
注:内存对齐
I. 4字节对齐
II. 如果结构体中的所有成员的数据宽度均未达到4字节,按最大成员数据宽度进行对齐。
示例:
struct std1{
int a; //4
char b; //1
//占空3
float c; //4
char d; //1
//占空3
double e; //8
}
sizeof(std1) = 24
struct std2{
char c; //1
//占空1
short s; //2
};
sizeof(std2) = 4
2. 共同体
所有成员使用同一块内存
union st{
char a[2];
short b;
};
int main(int argc, char *argv[])
{
union st s;
s.b = 0x1122;
fprintf(stdout, “%x, %x\n”, s.a[0], s.a[1]);
return EXIT_SUCCESS;
}
结果:22,11
判断当前系统是大端系统还是小端系统:
在上例基础上修改
s.b = 0x0001;
fprintf(stdout, "这是%s端系统\n", s.a[1] ? “大” :”小”);
3. 位段结构
struct st{
unsigned int a : 5; //5表示位数
unsigned int b : 8;
unsigned int c : 9;
unsigned int d : 1;
};
sizeof(struct st) = 4
对齐方式和结构体相同,位数不能超过前边类型的宽度
C语言中有42个运算符
赋值 |
= |
+= |
-= |
/= |
%= |
*= |
|
6 |
算术 |
+ |
- |
* |
/ |
% |
++ |
-- |
7 |
关系 |
> |
< |
<= |
=> |
== |
!= |
|
6 |
逻辑 |
&& |
|| |
! |
|
|
|
|
3 |
|
*(取值) |
&(取址) |
|
|
|
|
|
2 |
位运算 |
& |
| |
^ |
~ |
<< |
>> |
|
5 |
|
&= |
|= |
^= |
|
<<= |
=>> |
|
5 |
三元 |
? : |
|
|
|
|
|
|
|
逗号 |
, |
|
sizeof |
成员 |
-> |
. |
|
|
注:a << n 相当于 a*2^n
~1 为 -2 ~2 为 -3 ~3 为 -4
1 原码 0000 0001 取反后 1111 1110
-2原码 1000 0010 反码 1111 1101 补码 1111 1110
在计算机中负数都以补码形式存在,所以~1为-2
一共32个关键字
数据类型 |
|
void |
char |
int |
float |
double |
|
5 |
|
short |
long |
signed |
unsigned |
|
|
4 |
|
|
struct |
union |
enum |
typedef |
sizeof |
|
4 |
|
存储 |
auto |
static |
register |
extern |
const |
volatile |
6 |
|
流程控制 |
跳转 |
return |
continue |
break |
goto |
|
|
4 |
分支 |
if |
else |
switch |
case |
default |
|
5 |
|
循环 |
for |
do |
while |
|
|
|
3 |
为复杂声明定义简单别名
示例:
声明一下变量
a. 一个整型
b. 一个整型指针
c. 一个指向整型指针的指针
d. 十个整型数组
e. 十个整型指针数组
f. 十个整型数组的指针
g. 一个指向函数的指针,此函数有一个整型参数和一个整型返回值
h. 一个存放(f)中描述函数指针的十个元素的数组
int a; typedef int Int; Int a;
int *p; typedef int * Pint; Pint p;
int **pp; typedef int **Ppint; Ppint pp;
int a[10]; typedef int A[10]; A a;
int *a[10]; typedef int *PA[10]; PA a;
int (*p)[10]; typedef int (*AP)[10]; AP a;
int (*p)(int); typedef int (*PF)(int); PF p;
int (*p[10])(int); typedef int (*PFA[10])(int); PFA a;
注:使用typedef起别名时,只需将定义的变量名改为别名
存储类型 |
存储区 |
作用域 |
生存期 |
默认值 |
auto(默认) |
栈 |
声明时开始,出栈时结束 |
其作用域 |
随机值 |
全局 |
全局静态区 |
声明时开始,文件尾结束(可以扩展到程序的任意位置) |
编译时开始到程序结束时 |
0(各种零) |
register |
寄存器 |
(同auto) |
(同auto) |
随机值 |
static |
(同全局) |
声明时开始,文件尾结束(可以在当前文件内扩展) |
(同全局) |
0 |
局部静态区 |
(同auto) |
(同全局) |
0 |
|
extern |
|
(同全局或static全局) |
(同被扩展变量) |
|
注:
a. auto仅限局部变量(全在栈里)
b. extern 不是存储类型,主要用于扩展全局变量的作用域
例:extern int a; //把a的作用域扩展到当前位置
extern
int a = 5; //不是声明语句(不分配内存), 不能直接初始化
在程序编译过程中,如果找不到一些函数的声明,在主函数中进行声明时,
若该函数是主函数外的文件中,通常在所声明函数前加extern
如:extern void fun();
c. 寄存器变量register声明要求: 泛整型
局部变量
d. static 函数定义
如:static int fun() { }
限定函数作用域为文件作用域
static 全局变量声明
如:static int a = 9;
限定全局变量为文件作用域,仅可在当前文件内extern
volatile int a; //防止编译器对此变量优化
通常使用在:
a. 两线程通信时,对通信变量进行修饰
在线程间进行通信时,由于一方某一变量的读取频次过高,在没有volatile关键字修饰时,编译器会将该变量设为寄存器变量,从而无法实现通信
b. 串口通信中
在串口通信中,接收到的数据(串行通信)存储在一变量中,系统对该变量的连续访问,可能导致编译器优化该变量
编译器优化:
编译器会将频次访问过高的变量,自动优化为寄存器变量
在C语言中— { 进栈(开始建栈)
} 出栈
(每一个大括号{}即一个栈)
通常变量在栈开始时声明,即(大括号){后声明,不可以在执行语句后声明(C89标准)
(手动)—— malloc
动态申请
手动释放 —— free
注:内存泄露
在函数命名时通常采用见名知意,因此在应用别人的函数或库时,有init函数名的函数中,可能会有申请内存的操作。同时会在destory/close函数名的函数中会释放。
如: void func( )
{
int *p;
p = malloc(100);
。
。
。
}
该函数在开始申请了内存,应该在函数结束时,释放p
#define 宏名 宏体
宏定义是在预编译阶段,进行单纯的宏替换
1) 宏定义时,
宏体中出现运算符,必须将宏体用括号括起来;如果是带参
宏,宏体中的宏参,必须用括号括起来。
如:#define DIV(a, b) ((a)+(b))
2) 头文件
< > 在默认头文件目录查找
“ ” 现在当前目录下查找,再到默认头文件目录下查找
3) 条件编译
#ifndef DEF_H //如果没有定义这个宏(该头文件之前的代码中)
#define DEF_H //定义一个DEF_H宏
#define VALUE 8
#endif //DEF_H 判断对应哪个if,防止缺省
防止头文件重复,宏名起发为当前文件名称大写
示例:
a. 定义一个宏,宏值为一年中有多少秒(忽略闰年)
#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL
b. 定义一个宏MIN, 求两数较小值。
#define MIN(a, b) ((a) < (b) ? (a) : (b))
c. 定义一个ARRAY_SIZE,计算数组长度
#define ARRAY_SIZE(a) ((sizeof(a)) / (sizeof(a[0])))
宏定义与typedef别名的区别:
#define PINT int*
Typedef int * Pint;
Pint p1, p2;
PINT p3, p4; //p4数据类型为int,其他均为int*
所谓数组,就是相同数据类型的元素按一定顺序排列的集合,就是把有限个类型相同的变量用一个名字命名,然后用编号区分他们的变量的集合,这个名字称为数组名,编号称为下标。
int a[4];
数组名a即数组首元素的地址,是一个常量
int a[4] = {1, 2, 3, 4};
相当于
int a[4] = {
[0] = 1,
[1] = 2,
[2] = 3,
[3] = 4,
};
注:第二类初始化可以对特定元素进行初始化,没有顺序的要求(可以打乱先后次序)
char S[5];
数组的地址 &S S+1
内存分布表示
|
|
|
x |
x |
|
x |
|
数组首元素地址
S
S+1
char [5] //5个char的数组
5个char的数组的地址-即数组指针 char (*p)[5]
指针数组 char *p[5]; //数组中有5个char*
指针定义符 * 左结合
int main(int argc, char *argv[])
相当于——char **argv
(参考附命令行参数)
argv |
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
数据0 |
||
|
||
|
||
数据1 |
||
|
||
|
||
数据2 |
![]() |
A(数据0)的存放的地址,即其指针,
它存放在*A(地址0),而存放*A的地址
,即*A指针,存放在地址argv处内容
是*(*A) 相当于 argv = **A
![]() |
推广
字符数组char a[](数据0)的存放地址,
即数组*a的地址(数组首元素的地址a),
它存放在(地址0)处,内容*a,而存放
*a空间的地址*(*a),存放在地址argv处
(argv = **a 相当于 argv = char *a[])
#include <strings.h>
a. 清零
void bzero(void *s, size_t n); //置字节字符串前n个字节为零包含’\0’
bzero(buf, sizeof(buf)); //清零整个数组
该函数也可用于对结构体进行初始化复位。
b. 初始化
void *memset(void *s, int c, size_t n); //将s中的前n个字节用c代替并返回s
c.
复制(因为数组无法整体赋值,如a[5] = b[5])
void *memcpy(void *dest, const void *src, size_t n); //从源src所指的内存地址起始位置复制n个字节到目标dest所指的内存地址起始位置
结构体命名结构
struct
{
int a,
类型 b,
c;
}st;
变量名
结构体嵌套——便于内存归类
功能:字符串转化成长整型
原型:long int strtol(const char *nptr, char **endptr, int base);
nptr —— 目标字符串
endptr —— ??
base —— 目标字符串所转的进制数
示例: char *s = “131412312s”;
Char *p; long n;
N = strtol(s, &p, 10); //该字符串转化成十进制
注:strtoll 转long long
strtod 转double
strtof 转float
功能:(用户输入)
可以用作键盘输入:fgets(key,n,stdin)且还必须:key[strlen(key)-1]='\0'
还有种程序经常使用的方法:key[strlen(key-1)]=0x00;
与gets相比使用这个好处是:读取指定大小的数据,避免gets函数从stdin接收字符串而不检查它所复制的缓存的容积导致的缓存溢出问题
原型:char *fgets(char *s, int size, FILE *stream)
*s: 字符型指针,指向用来存储所得数据的地址。
size: 整型数据,指明存储数据的大小。
*stream: 文件结构体指针,将要读取的文件流。
从文件结构体指针stream中读取数据,每次读取一行。读取的数据保存在buf指向的字符数组中,每次最多读取size-1个字符(第size个字符赋'\0'),如果文件中的该行,不足size个字符,则读完该行就结束。如若该行(包括最后一个换行符)的字符数超过size-1,则fgets只返回一个不完整的行,但是,缓冲区总是以NULL字符结尾,对fgets的下一次调用会继续读该行。函数成功将返回s,失败或读到文件结尾返回NULL。因此我们不能直接通过fgets的返回值来判断函数是否是出错而终止的,应该借助feof函数或者ferror函数来判断。
原型:long int strtol(const char* nptr, char** endptr, int base);
功能:将字符串中的数字转成base进制数(以数字开头的字符串)
返回值:
原型:
注:在VC中可以是用itoa()函数,进行进制转换
如:
char buf[50];
itoa(10, buf, 2); //将数字10转换成二(2)进制后,存到buf字符数组中成字符串
野指针——只声明,没有初始化
如:
{
struct sDateTime *pDT;
pDT->time.second = 14;
}
此时,pDT为野指针,它指向内存中的任意一段内存空间,而该段内存可能对该指针没有访问权限或没有所指向的内容,而导致非法访问。
段错误在windows下容易导致蓝屏
正确使用:
{
struct sDateTime dt;
struct sDateTime *pDT = &dt;
pDT->time.second = 14;
}
注:在程序中声明一个变量,就是在内存中开辟一段内存空间(大小视变量类型而定);而声明一个指针则是给定一个内存地址,而只有当一段空间与一个地址“绑定”的时时候(也就是取址、赋值),该指针才有意义
![]() |
(创建进程) —— 复制所有数据
|
内存中
a只有一个 (共享代码)
父进程
子进程
|
||||
![]() |
||||
a有两个
![]() |
![]() |
无论任何进程,父子进程数据是私有的,代码是共享的
|
函数调用
![]() |
修改a值 读取a值 (线程间数据共享——通信)
优点: a. 数据共享
b.代码共享
c.多核处理器可使不同线程在不同处理器上
速度快,安全性低
0 |
.0 |
0L |
.0F |
0UL |
‘\0’ |
0U |
NULL == ((void *) 0 ) |
注:字符串末尾有一个’\0’, 代表该字符串结束
字符串数据类型 “abc” 为 const char *
int main(int argc, char *argv[])
![]() |
![]() |
||
命令行参数个数含命令本身 列表
如:./waveplayer xp.wav xp1.wav
argc = 3 argv[0] argv[1] argv[2]
(参考二级指针)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Rgb565
|
|
|
|
|
0 |
0 |
0 |
R (r & 0xF8)<< 8
|
|
|
|
|
|
0 |
0 |
G (g & 0xFC) << 3
|
|
|
|
|
0 |
0 |
0 |
B (b >> 3)
Rgb565 = ( (r & 0xF8) .<< 8) | ((g & 0xFC) << 3) | ( b >> 3);
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char *argv[])
{
uint8_t r = 0xFF;
uint8_t g = 0xCC;
uint8_t b = 0x99;
uint16_t rgb = 0;
rgb = ((r & 0xF8) << 8) |
((g & 0xFC) << 3) |
(b >> 3);
fprintf(stdout, "%4X\n", rgb);
return EXIT_SUCCESS;
}
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef union{
uint16_t rgb;
struct {
uint16_t b : 5;
uint16_t g : 6;
uint16_t r : 5;
}colors;
}Color;
int main(int argc, char *argv[])
{
uint8_t r = 0xFF;
uint8_t g = 0xCC;
uint8_t b = 0x99;
Color color;
color.colors.r = r >> 3;
color.colors.g = g >> 2;
color.colors.b = b >> 3;
fprintf(stdout, "%04X\n", color.rgb);
return EXIT_SUCCESS;
}
GUNMakefile 高
规则文件 makefile 优先级
Makefile(一般) 低
一般编写使用Makefile命名,其他两个多用于在一个项目中存在检测
|
语法:
![]() |
|||
![]() |
|||
规则:
i. 先递归、 后迭代
(检测依赖关系)(根据目标与依赖的时间关系,决定是否重新执行规则里的命令)
ii. 在规则文件中,第一个目标为默认目标,如果在下达make命令时,不指定目标,那就使用默认目标,为递归结点。
也可以在make时,指定一个目标
iii. 没有依赖的目标为伪目标,最好在此目标之上先做说明。
如:PHONY:clean
clean:
rm –f circle.o area.o main.o
I. 自定义变量
赋值:变量名=值列表(空格分隔) #多行加转义符
引用:$(变量名)
注:
= 引用时才展开变量值
:= 赋值时直接展开变量(替换后不变)
+= 连接形成列表
?= 如果原来变量没有赋值时,才有效
II. 预定义变量
$@ |
本条规则的目标 |
|
$^ |
本条规则所有依赖 |
|
$< |
本条规则第一个依赖 |
|
CC |
默认的C编译器 |
|
CFLANGS |
指定编译阶段的参数 |
|
III. Make的推断
推断简单的编译命令
多目标生成时,可将多个目标作为依赖关系,重新设定一个目标
a. qmake -project #使用QT自带工具生成一个round.pro项目文件
b. qmake #通过xxx.pro项目文件生成Makefile编译规则文件
c. vi Makefile文件,对其根据需要修改 编译参数
d. make #编译 指定编译器
头文件指定
库名指定
SRC=area.o \
circle.o \
volume.o
CC=gcc
CFLAGS=-Wall -O3 -I.
AR= ar
LDLAGS=-lm //自定义变量
all : libround.so libround.a round
libround.so : $(SRC)
$(CC) -fpic -shared -o $@ $(SRC)
libround.a : $(SRC)
$(AR) -r $@ $(SRC)
round : $(SRC) main.o
$(CC) $^ -o $@ $(LDLAGS)
area.o : area.c
circle.o : circle.c
volume.o : volume.c
main.o : main.c round.h
.PHONY : clean
clean :
rm -f $(SRC) main.o
在Linux中一切皆文件,而设备文件是为了统一设备访问接口
|
C library
User
space (用户模式)
![]() |
虚拟文件系统
![]() |
Kernel space (内核模式)
drive drive drive
驱动
device device device
设备
![]() |
Hardware platform[硬件平台]
注:buffer 缓冲区,大小为8192bytes=8kb
在程序运行中缓冲区满或遇到换行字符或程序结束时,才向标准输出设备上输出内容。
文件的使用
系统调用 文件描述符(int) 识别内核访问的设备文件
标准C库 文件指针(FILE*)
文件描述符范围0~65535,每打开一个文件,文件描述符的值尽可能保持最小值。
stdin
0
系统开启后,三个文件默认打开 stdout 1
stderr 2
<unistd.h>
ssize_t write(int fd, const void *buf, size_t count)
功能:指针buf地址开始,将连续个count个字节,写入到fd文件描述符所对应的文件中。
返回值: >0 实际写入的字节数
0 未写入数据
-1 失败
出错:设置errno
注:
size_t unsigned int 表示大小、数量、无符号
ssize_t signed int 表示大小、数量、符号
void * 无类型指针,可以指向任意类型的内存地址
const void * 常数据指针,不能通过该指针修改它所指的数据
<unisstd.h>
int close(int fd)
功能:关闭文件描述符为fd的文件
返回值:成功 0; 失败 -1
出错:设置errno
注:
程序中一般不对close进行出错处理
只针对进程关闭文件,如果一进程与其克隆进程,同时使用一个文件;其中一进程通过close关闭该文件,另一进程还能正常使用。
1. <errno.h>
errno //错误号
<string.h>
char *strerror(int no) 根据错误号取出出错信息
2. <stdio.h>
perror(“write”); 在write后加上冒号和出错信息,然后输出到stderr
注:在if条件判断时,出现==和常数时,常数一般写==左边,防止将关系运算符写成赋值运算时,不报错
在编码时,通常使用
return –errno; //好处?
<unisstd.h>
ssize_t read(int fd, void *buf, size_t count)
功能:从fd代表的文件中,读取count个字节的数据,存入buf地址中。
返回值: >0 实际读到的字节数
0 读到任何数据
-1 失败
出错:同write
注:
string.h头文件包含了strings.h
BUFSIZ是个宏,定义于stdio.h中,其值为系统缓冲区大小(8192byts=8kb)
<sys/types.h>
<sys/stat.h>
<fcntl.h>
int open(const char *name, int flags) //打开已存在文件
int open(const char *name, int flags, mode_t mode) //不存在时新建并打开
功能:以flags指定方式打开一个name指定文件
返回值:成功——返回文件描述符
失败——-1
出错:同write
打开方式flags:
O_RDONLY |
只读 |
O_WRONLY |
只写 |
O_RDWR |
读写 |
O_CREAT |
创建 |
O_SYNC |
同步 |
O_TRUNC |
若存在则清空 |
O_APEND |
追加模式打开,文件打开后文件指针指向文件尾(其他默认都在文件首,多次写时将覆盖之前文件内容) |
多个参数时,使用按位或链接。如:
O_RDWR | O_CREAT
如果flags中包含了O_CREAT,则必须使用三参的open函数
mode:用于指定文件权限、属性等。(见附文件掩码)
如:
S_IRUSR | S_IRGRUP | S_IROTH
Open(FILENAME, O_WRONLY | O_TRUNC, 0644) // 八进制权限表示
<sys/ioctl.h>
int ioctl(int df, int cmd,
…)
(命令或请求) 无 (cmd命令没有参数)
驱动程序头文件 地址(根据cmd参数决定)
/usr/include/linux/*.h
#include <linux/xxx.h>
![]() |
统一的设备控制接口(UNIX统一规定)
![]() |
同类设备驱动兼容上层控制接口
![]() |
示例:将通道数设为2
声卡设备使用:
i. 复位
ii. 设置声道、采样率、位数等。。。
注:幻数 —— 主要用于控制(ctl)命令。
1)
数据方向 无
写( 驱动)W
读( 驱动)R
2)
设备编号(在幻数列表文件)
3)
命令值
4)
数据宽度
示例:
#define SNDCTL_DSP_CHANNELS _SIOWR('P', 6, int)
功能:改变文件读/写偏移量
<sys/types.h>
<unistd.h>
原型:off_t lseek(int fd, off_t offset, int whence)
SEEK_SET 文件开始
whence SEEK_CUR 当前位置
SEEK_END 文件末尾
返回值:函数调用后的文件指针偏移量(以字节为单位)
-1 代表失败
例:lseek( fd, -100, SEEK_CUR)
功能:将文件映射到内存(相当于数组)
<sys/mman.h>
原型:
void *mmap (void* start, size_t length, int prot, int flags, int fd, off_t offset)
start——用于指定映射地址,NULL代表由系统决定映射地址
length——想要映射的长度(单位字节)
PROT_READ 只读
prot——映射权限 PROT_WRINT 只写
PROT_READ | PROT_WRINT 读写
flags——映射模式 MAP_SHARE 共享(内存改—文件变)
MAP_PRIVATE 私有(内存改—文件不变)
fd——文件描述符
Offset——映射的文件偏移(相对于文件首的偏移量),必须为分页大小的整数倍 n*getpagesize() //获取系统分页大小
返回值:成功——返回映射地址
失败——(void*)-1
如:if((void*)-1 == ptr)
原型:int munmap(void *p, size_t length) //参数与mmap对应
返回值: 成功 0
失败 -1
目的:将未经过压缩的wav音频文件,通过文件操作播放
![]() |
内存
malloc或数组 open 只写
![]() |
![]() |
WAV文件 声卡设备文件
open 只读
过程化:
1. 打开wav文件
2. 打开声卡设备文件(/dev/audio)
3.
从wav文件中的数据读到内存中
4. 将内存中的数据写到声卡设备文件 循环直至wav文件读取完毕
5. 关闭声卡设备文件
6. 关闭wav文件
实现1:
如何只提取结构体中的成员
方法一:直接使用read将文件头部分读入结构体所在内存
方法二:
1. 数组的内存赋值给结构体的内存,使用memcpy()
2. 只循环一次,结束循环
虽然可以读取,但在此处不可行
模块化(程序复用)
播放流程 2 1 2.5 3 4 6 5
1.初始化音频文件
a.打开音频文件
b.读取音频参数
c.检查文件合法性
2.初始化音频设备
2.
a.打开音频设备
2.5.
b.设置工作参数
3.读取音频文件数据
4.写音频数据——声卡
![]() |
5.关闭音频设备
6.关闭音频文件
分类:
音频文件相关:1, 3, 6 (wav.c)
音频设备相关:2, 2.5, 4, 5 (soundcard.h)
wav.c
序号 |
函数名 |
所需参数(结构体) |
返回值 |
|
1 |
initWaveDecoder |
文件名 |
采、声、位、文件描述符 |
错误号(返回值int) |
3 |
getWaveDate |
文件描述符、大小、存放位置,偏移量、实际数据长度 |
错误号(返回值int) |
|
6 |
closeWaveFile |
文件描述符 |
错误号(返回值int) |
|
soundcard.c
序号 |
函数名 |
所需参数(结构体) |
返回值 |
|
2 |
OpenSndDevice |
设备名 |
文件描述符 |
错误号(返回值int) |
2.5 |
setSndDevice |
文件描述符、采、声、位 |
错误号(返回值int) |
|
4 |
writeSndDevice |
文件描述符、存放位置(地址)、实际长度、 |
错误号(返回值int) |
|
5 |
closeSndDevice |
文件描述符 |
错误号(返回值int) |
|
注:对固定不变的参数,在函数形参定义时,通常使用const修饰
错误处理 /sndDevice.c
man [级别] 内容
分级:
1 shell命令
2 系统调用函数(与内核直接通信)
3 C库函数
4 设备
5 配置文件
6 游戏
7 协议(设备相关)
8 网络相关协议
位置:/usr/share/man/man[1-8]
限制系统文件权限,在初始情况下,文件权限666目录权限777,系统通过文件掩码进行默认权限的限制
默认文件权限获取:
iii. 文件必须去除可执行权限
iv. 再用这个权限与掩码按位取反后的值进行与操作
查看系统文件掩码
命令:umask
0022(八进制) 000 010 010
取反 111 101 101
文件权限 110 110 110 ‘与’ (初始权限)
110
100 100 —— _rw__r__r__ (创建文件的默认权限)
部分关键字不亮解决方法
在/usr/share/vim/vim70/syntax/c.vim中查找相似的预定义变量,将该变量添加在后面。
<stdlib.h>
原型:int system(const char *cmd)
返回值:cmd运行的结果
用处:进程替换
man 3 exec
原型:int execl(const char *path, const char *arg, …);
功能:启动一个进程
path —— 命令路径,该进程替换当前正在运行的进程,如#define PATH “/bin/ls”
arg —— 命令参数列表,相当于命令行输入的内容
注:参数列表中最后一个参数为必须为NULL(哨兵)
<sys/types.h>
<unistd.h>
原型:pid_t fork(void);
功能:创建一个子进程
参数:无
返回值:失败 -1
成功 父进程返回子进程ID
子进程返回0
附: pid_t getpid(void); //获取当前进程ID
pid_t getppid(void); //获取当前父进程ID
僵尸进程:只占用ID,不占用内存和处理器资源
Fork创建的父子进程,父进程先于子进程结束,子进程就会被INIT进程托管,(进程号将变为1)此时这个进程称为“守护进程”;反之子进程先于父进程结束,子进程会等待父进程退出,而一同退出。此时的子进程不占用任何处理器和内存资源,仅占用一个进程ID,这时子进程被称为僵尸进程。
<signal.h>
原型:int kill(pid_t pid, int sig);
返回值:失败 -1 成功 0
注:fork创建的父子进程间通信
守护进程设置:
setuid(0); //使当前进程脱离用户会话期
chdir(“/”); //改变当前进程工作路径为根
umask(0); //改变文件掩码值为0000
<signal.h>
typedef void (* sighandler_t) (int); //函数指针
原型:sighandler_t signal(int signum, sighandler_t handler);
signum——信号值
handler——信号处理函数
功能:捕获信号,此函数调用后,当前进程再次收到signum信号时,将暂停当前代码,自动调用handler指向的函数,当handler指向的函数运行完毕后,返回暂停处继续向下执行。
注:不是所有信号都可以被捕获,如:SIGKILL信号不能被捕获
返回值:为与信号原来关联的函数指针
附:
a. 调用的目的:当该进程收到signum指定的信号时,自动调用handler指定函数
b. 每个进程对一些信号都有默认的处理函数
defaultprocessInit funInit signal(SIGINT, p); 信号表 pSIGINT defaultprocessInit funInit p=signal(SIGINT, funInit); defaultprocessInit 信号表 pSIGINT
A 进程启动 B调用signal C
再次调用signal
SIG_DEF —— 系统默认处理函数
SIG_IGN —— 忽略信号
<unistd.h>
原型:unsigned int alarm(unsigned int seconds);
功能:在seconds后向当前进程发送一个SIGALRM信号
原型:int pause(void)
功能:暂停函数,以阻塞方式暂停当前进程
阻塞方式——使该进程占用很少的处理器资源
<sys/time.h>
原型:int setitimer(int which, const struct itimerval *value, struct itimerval *oldvalue)
参数:
which
ITIMER_REAL //系统提供,只要处理器工作,定时器就有效,产生SIGALRM信号
ITIMER_VIRTUAL //进程中虚拟的,只要进程运行时才有效,产生SIGVTALRM信号
value——设置定时参数
struct itimerval{
struct timeval it_interval; //间隔时长
struct timeval it_value; //启动时长
};
注:it_interval、it_value二者中有一项为0时,停止定时器工作
i—— 间隔(interval) t —— 时间(time)
oldvalue——向调用处返回原来的定时器参数,如果不需要,调用时写NULL
struct timeval{
long tv_sec; //秒
long tv_usec; //微秒
};
例如:
<stdio.h>
原型:FILE* popen(const char *cmd, const char *type);
功能:执行命令cmd,并与此命令启动的进程间创建一个管道,根据type确定管道与命令间的数据方向。
type |
当前进程 |
数据方向 |
cmd进程 |
“r” |
FILE* |
|
stdout |
“w” |
|
fwrite |
stdin |
附:
size_t fread(void *ptr, size_t size, size_t nmemb, FILE* stream);
实际读的次数 读次数 每次都大小
如:
<unistd.h>
原型:int pipe(int filedes[2]);
注:函数形参中出现数组形式的写法时,实际上形参的数据类型不是数组,而是指针,之所以写为数组形式,是为了告知函数调用者,这段内存至少需要多大,如:int pipe(int filedes[2]); //filedes数据类型为int*,而且filedes指针要保证其指向2*sizeof(int)这么大的可读写内存空间。
![]() |
open open
只读 只写
原型:int mkfifo(const *pathname, mode_t mode);
参数:mode——权限
注:仅创建,打开使用open()
原型:int unlink(const *pathname);
返回值: 成功 0
失败 错误号
注:(1) 管道读写要同时打开
(2) 如果写端关闭,读端将不再阻塞
封装信息
本地IP |
本地端口 |
协议 |
远程端口 |
远程IP |
注:网络中的数据按大端模式传送
至少封装一半信息即可通信(前半部分或后半部分)
TCP通信——C/S架构
服务器IP 0.0.0.0 监听端口 1234 (监听的套接字接受客户端连接) Accept请求客户端连接创建新的套接字
再随机分配一个端口
创建新套接字文件(用于客户端通信)
127.0.0.1 1234 端口随机
服务器
客户端
连接
数据通信
附:
TCP——流式通信(分片传输)
UDP——数据报
常见端口
|
端口号 |
https:// |
443 |
http:// |
80 |
ftp:// |
21 |
mail:// |
25(发)/110(收) |
<sys/types.h>
<sys/socket.h>
原型:int socket(int domain, int type, int protocol);
功能:创建套接字文件
参数:domain——用于指定通信域 PF_UNIX/PF_LOCAL
—本机通信
PF_INET —— 远程
type——通信类型: SOCK_STREAM — 流式(TCP)
SOCK_DGRAM — 数据报(UDP)
protocal——协议 0
返回值:成功——返回套接字文件描述符
失败——-1
注:所创建的套接字文件在VFS内核中(虚拟)
<sys/types.h>
<sys/socket.h>
原型:int bind(int sockFd, const struct sockaddr *srvAddr, socklen_t addrLen);
功能:绑定
参数:sockFd —— 套接字文件描述符
addrLen——sizeof(struct sockaddr)
srvAddr—a. struct sockaddr结构不能直接使用,要使用struct sockaddr_in
结构替代之。
sin_family 域 AF_UNIX/AF_LOCAL
AF_INET
b. struct sockaddr_in sin_port 端口号(按大端存储的端口号)
成员
sin_addr.s_addr IP地址(按大端存储)
struct
in_addr 数据类型
返回值:成功 0 失败 -1
注:使用struct sockaddr 结构体之前必须先清零
端口号、IP地址转换(大端存储)
h——host n——network
short——端口 long——IP地址
如:ntohl() IP地址网络转主机
<arpa/inet.h>
unist32_t htonl(uint32_t hostlong);
uint16_t htons(uint16_t hostshort);
uint32_t htohl(uint32_t netlong);
uint16_t ntohs(uint16_t netshort);
以上函数主要是将我们输入的ip、端口号,转换成计算机存储的大端模式,或将存储的大端模式转换我们平时的典型IP
输入点分制IP的转换
<sys/socket.h>
<netinet/in.h>
<arpa/inet.h>
char* inet_ntoa(struct in_addr in); //sin_addr.s_addr转为点分制IP
in_addr_t inet_addr(const char* cp); //点分制IP转struct in_addr
返回值:INADDR(0)——ip相当于0.0.0.0
INADDR_NONE(-1)——ip相当于255.255.255.255
注:sin_addr.s_addr、in_addr_t 的数据类型为struct in_addr
原型:int listen(int sockFd, int backlog);
功能:创建监听
参数:sockFd——文件描述符
Backlog——等待队列最大长度
返回值:成功 0 失败 -1
示例:创建TCP监听函数结构体
typedef struct{
char ipAddr[17]; //ip地址
#define LOCAL_SOCKT PF_UNIX
#define REMOT_SOCKT PE_INET
char domain; //域使用上面两个宏定义
uint16_t port; //端口
int sockFd;
int backlog;
}IpInfo;
原型:int connect(int sockFd, const struct sockaddr* srvAddr,
socklen_t addrLen);
功能:客户端连接到服务器
参数:同bind
返回值:成功——0
失败—— -1
原型:int accept(int sockFd, struct sockaddr* addr, socklen_t sockLen);
功能:接受客户端连接
参数:addr——向服务器返回客户端IP信息
sockLen——向服务器返回客户端IP信息结构的长度
返回值:成功——服务器上用于与客户端通信的套接字文件描述符
失败——-1
注:addr的使用:被清零的struct sockaddr结构体的内存地址
sockLen使用:被设置为sizeof(struct sockaddr)大小的socklen_t变量的内存
如果不想获取客户端的IP(信息)、port时, addr可传NULL
示例:
struct sockaddr_in ipAddr;
socklen_t sockLen;
sockLen = sizeof(ipAddr);
bzero(&ipAddr, sockLen);
目的:在客户端输入shell命令,传到服务器上执行,并将执行后的结果传回到客户端显示
二者之间数据传输需要自定义协议
字节数 2 2 n
大小 |
类型 |
数据 |
大小——数据长度
类型——命令还是返回数据
‘P’——请求提示符
‘p’——返回提示符
‘C’——请求执行命令
‘c’——返回命令结果
自定义协议结构:
typedef struct{
uint16_t type;
uint16_t dataLength;
uint16_t maxLength;
char *data;
}Data;
server
client
F
F
T
T
socket
![]() |
F
T
![]() |
特点:消耗资源、编程简单、循环服务器在同一时刻只能响应一个客户端的请求。
用途:用于客户端处理速度快,不需要并发处理的
示例代码:/work/socket/tcp/tcp1
socket
![]() |
fork
pid=0(子)
r/w
pid=1
![]() |
F
T
特点:并发处理,消耗资源较大(数据私有),启动速度低;多客户端数据私有,保证了数据安全
示例代码:/work/socket/tcp/tcp2
socket
![]() |
Select—同时监听多个文件描述符的可读、可写、异常等状态,此函数调用后,被其监听的描述符无响应时阻塞,一旦多个文件描述符之一响应时,阻塞结束
优点:占用资源少,响应速度快
缺点:多客户端数据共享,安全性低
问题:
关联多个描述符
判断哪个描述符响应(测试(FD_ISSET)是否与句柄关联)
select使用
注:多个客户端,多个客户端信息(即IpInfo结构),采用结构体指针数组存储。而数组的下标与客户端文件描述符关联
示例代码:/work/socket/tcp/tcp3.1
后台运行的程序,可做守护进程
流程:
1)umask();
2)chdir();
3)setuid();
4)close all file
详见进程
示例:
[时间 IP 端口 状态]
工作目录:root=/work
日志文件:logfile=/var/log/rmshell.log
原型:int shoutdown(int s, int how);
功能:关闭部分全双通连接
参数:s——套接字文件描述符
how——SHUT_RD 读
SHUT_WR 写
SHUT_RDWR 读写
注:shoutdown与close区别:
shoutdown(s, SHUT_RDWR); //针对套接字的设备(该套接字设备在以后不用是时,可用shoutdown关闭)
close(s); //关闭针对当前进程
数据类型——fd_set //监听句柄
声明:fd_set rfds //变量
使用:&rfds //指针
1)void FD_SET(int fd, fd_set *set); //关联文件描述符(一次关联一个)
2)void FD_ZERO(fd_set *set); //消除句柄中的所有描述符
3)int FD_ISSET(int fd, fd_set *set); //测试该描述符是否响应
返回值:0——没关联 1——关联
原型:int select(int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds,
struct timeval *timeout);
功能:监听多个文件描述符的状态
参数:nfds——所监听的文件描述符最大值加1
rfds——读状态监听
wfds——写状态监听
efds——异常监听
timeout——超时
注:读、写、异常至少选一个监听,不需要调用可传NULL,不设置超时时间也可传NULL
返回值:失败——-1 (该设备没有监听机制)
成功——1
超时——0
注:listen与select函数的区别:
listen针对tcp服务器,对网络端口进行监听,用于在监听端口提供服务。
select监听用于对文件描述符的可读、可写、异常等状态的侦测,它不仅仅局限于套接字文件描述符,而是所有文件描述符,只要对应的设备文件支持阻塞,即可使用此函数进行监听。select函数调用后,程序进入阻塞状态,直到设备监听状态响应时,才退出select函数调用。
|
![]() |
bind
只有接受数据时才需要绑定bind
![]() |
原型:ssize_t sendto(int s, const void *buf, size_t len, int flags,
const struct sockaddr *addr, socklen_t addrLen);
功能:发送数据——相当于write() + connect() 合体
原型:ssize_t recvfrom(int s, void *buf, size_t len, int flags,
struct sockaddr *addr, socklen_t addrLen);
功能:接收数据——相当于read() + conect() 合体
原型:int setsockopt(int s, int level, int optname, void *optval, socklen_t *optLen)
功能:设置套接字参数
参数:s——文件描述符
参数 |
level |
optname |
optval |
optLen |
|
SOL_SOCKET |
SO_BROADCASE(是否允许广播) |
int |
0或1 |
SO_DONTRDUTE(不查找路由) |
int |
0或1 |
||
SO_RECVBUF(接受缓冲区大小) |
int |
|
||
SO_SNDBUF(发送缓冲区大小) |
int |
|
||
SO_ERCVTIMED(接受超时时间) |
struct timeval |
|
||
SO_SNDTIMED(发送超时时间) |
struct timeval |
|
||
IPPROTO_IP |
IP_TTL (生存时间) |
int |
|
|
IPPROTO_TCP |
TCP_MAXSEG(TCP最大数据段大小,切片大小) |
int |
|
如:
int t = 1;
setsockopt(s, SOL_SOCKET, SO_BROADCASE, &t, sizeof(t));
参考十二ioctl()函数
参数:cmd——FIONRED
arg——int*
示例:size_t n;
int sockFd;
ioctl(sockFd, FIONRED, &n);
fprintf(stdout, “%d bytes ready read\n”, n);
buf = (char *)malloc(n);
read(sockFd, buf, n);
流程
![]() |
fork
子
父
sendData reciveData
示例代码:/work/socket/udp/udpchat.c
netstat –an | grep 80 #查看本机http服务是否开启
编写程序将最先进行错误判断,将可能最容易出错(或出现的这个错误会使一些代码的运行失去意义)的应先编写,进行错误处理
使用switch—case 可进行错误判断处理,使用户自定义错误信息
switch(ret)
{
case TCPERR_INVADDR:
fprintf(stderr, "Invalid ip addr.");
break;
case TCPERR_LISTEN;
}
indent xxxx.c //格式化C代码后,会备份源码
函数:time();
gmtime();
常用数据库:mysql(C/S架构,网络端口3306)
sqlite——通讯录(基于文件[只能进行本地的数据读写])
(头、库)开发包
Mysql——API sever—数据服务
client—客户端shell
start
service mysqld stop
restart
mysql [-h 主机名或IP] [-u 用户名] [-p[密码]] [数据库名]
如:mysql –h 192.168.1.2 –u linfeng –p
注:MySQL默认数据库和用户新建数据库放在,/var/lib/mysql下
密码忘记或丢失可进行数据库重置的方式,重新登入数据库
a. 停止mysqld服务
b. rm –rf /var/lib/mysql/mysql #删除用户信息所在数据库mysql
c. 重新开启mysqld服务
show databases;
use test1;
drop database test2;
show table;
字段:user host password
用户的增、删、改可以对mysql.user表的相应操作来完成。
如:修改所有用户密码
update user set password=password(‘123456’);
密码通过password函数crypt方式加密成一个字符串(老版本16位,新版本41位)
查看密码的加密长度:
select length(password('123456')) from user; //长度均为16
加密:
ENCRYPT(,):使用UNIX crypt()系统加密字符串,ENCRYPT()函数接收要加密的字符串和(可选的)用于加密过程的salt(一个可以唯一确定口令的字符串,就像钥匙一样),注意,windows上不支持
DECODE(,):加密解密字符串。该函数有两个参数:被加密或解密的字符串和作为加密或解密基础的密钥。Encode结果是一个二进制字符串,以BLOB类型存储。加密成都相对比较弱
MD5():计算字符串的MD5校验和(128位)
SHA5():计算字符串的SHA5
grant all on *.* to linfeng@’%’ identified by ‘123456’;
‘%’——Mysql中通配符此处代表所有主机
整型 |
TINYINT |
一个字节 |
char |
BIT或BOOL |
一位(表真假) |
|
|
SMALLINT |
二个字节 |
short |
|
MEDIUMINT |
三个字节 |
|
|
INT或INTEGER |
四个字节 |
int |
|
BIGINT |
八个字节 |
long long |
|
实型 |
FLOAT[(m, n)] |
M显示宽度,n小数位数 |
Float |
DOUBLE[(m, n)] |
|
Double |
|
时间 |
TIME |
‘-838:59:59’到’838:59:59’ |
|
DATE |
‘1000-01-01’到’9999-12-31’ |
||
DATETIME |
前二者之和 |
||
TIMESTAMP |
‘1970-01-01 00:00:00’到2037年间的任意时刻 |
||
YEAR[(214)] |
|
||
字符型 |
CHAR(n) |
N个字符 |
|
VARCHAR(n) |
N个以内的字符 |
||
TEXT |
相当于VARCHAR(65535) |
||
二进制数 |
TINYBLOB |
最多256字节 |
|
BLOB |
最多65535字节 |
||
MEDIUMBLOB |
最多2^24字节 |
||
LONGBLIB |
最多2^32字节 |
数据库脚本扩展名为——xxx.sql
导出命令:
mysql [-h 主机名或IP] [-u 用户名] [-p[密码]] [数据库名] > xxx.sql
导入命令:
mysql [-h 主机名或IP] [-u 用户名] [-p[密码]] [数据库名] < xxx.sql
如:mysql –u linfeng –p test1 > test1.sql
检查开发包(mysql.h、libmysqlclient.so)是否已安装,命令有locate mysql,若未安装可挂载安装光盘进行安装:
rpm –ivhU `ls /media/Server/*.rpm | grep mysql | grep deve`
检测是否安装成功:
rpm –ql mysql-devel
MYSQL mysql_init(MYSQL *db);
注:MYSQL——连接句柄
使用方法:
a. 变量法
MYSQL db; //在栈中分配内存
mysql_init(&db); //一定必须成功
b. 指针法
MYSQL *db; //定义指针指向堆中的内存
db = mysql_init(NULL);
if(NULL == db)
{
//出错处理
}
void mysql_close(MYSQL *db);
MYSQL* mysql_real_connect(MYSQL *db, //初始化后的mysql句柄
const char *host,
const char *user,
const char *pass,
const char *db, //若无密码写””
unsigned short prot,
const char *unix_socket,
unsigned int client_flags);
参数:prot——端口号3306(写0也可以表示3306)
unix_socket——本地套接字文件名,一般写NULL
client_flags——客户端连接参数(一般写0,不设置)
CLIENT_ODBC — 面向ODBC编程使代码移植性更好
CLIENT_COMPRESS — 使用压缩协议
CLIENT_NO_SCHEMA — 不允许写(库.表.字段)这种形式
CLIENT_FOLIND_ROW — 不返回affectd(受影响的)行数,返回found(找到的)行数
返回出错的字符串描述:
const char * mysql_error(MYSQL *db);
返回错误号:
int mysql_errno(MYSQL * db);
int mysql_real_query(MYSWL *db, const char *sql, unsigned int length);
参数:sql——SQL语句
length——SQL语句的字符数量(即长度)
返回值:成功 0
失败 非0
MYSQL_RES —— 数据类型,存储结果集
MYSQL_RES* mysql_store_result(MYSQL *db); //将结果集存到客户端
MYSQL_RES* mysql_use_result(MYSQL *db); //将结果集存到服务器
返回值:成功——返回结果集指针
失败——返回NULL
MYSQL_ROW —— 数据类型,一行的存储类型
MYSQL_ROW mysql_fetch_row(MYSQL_RES *res);
返回值:成功——返回一条记录
失败——NULL
示例:
|
void mysql_data_seek(MYSQL *res, unsigned long long offset);
如:mysql_data_seek(MYSQL *res, int n);
//将结果集指针指向第n行
void mysql_free_result(MYSQL *res);
说明:释放由mysql_store_result()、mysql_use_result()、mysql_list_dbs()等为一个结果集合分配的内存。当你用完了一个结果集合时,你必须调用mysql_free_result()来释放它使用的内存。
unsigned int mysql_escape_string(char *to, const char *from, unsigned int length);
说明:把在from中的长度为length的字符串编码(如二进制数)转化为在一条SQL语句中可以发给服务器的转义的SQL字符串,将结果放在to中, 并且加上一个终止的空字节
编码的字符是NUL(ASCII 0)、‘\n’、‘\r’、‘\’、‘'’、‘"’
返回值:放进to的值的长度,不包括终止空字符。
unsigned long *mysql_fetch_lengths(MYSQL_RES *res);
说明:返回在结果集合内的当前行的列长度。如果你计划拷贝字段值,这个长度信息对优化也是有用的,因为你可以避免调用strlen()。另外,如果结果集合中包含二进制数据,你必须使用这个函数确定数据的大小,因为strlen()对包含空字符的任何字段返回不正确的结果。
空列和包含NULL的列的长度值是零。
返回值:成功——表示每列大小的无符号长整数的一个数组(不包括任何终止空字符)。
失败——NULL
注:在sprintf中使用%%——表示实际将输出一个%
在mysql数据库中进行wav音频文件的插入、查看、删除和播放
示例源码:/work/database/database
⑴ 对象
对象是人们要进行研究的任何事物,从最简单的整数到复杂的飞机等均可看作对象,它不仅能表示具体的事物,还能表示抽象的规则、计划或事件。
⑵ 对象的状态(属性)和行为
对象具有状态(属性),一个对象用数据值来描述它的状态(属性)。
对象还有操作,用于改变对象的状态,对象及其操作就是对象的行为。
对象实现了数据和操作的结合,使数据和操作封装于对象的统一体中
函数——不占内存
虚函数——占4字节内存(相对于C语言中函数指针)
类 变量——(对象)私有
静态变量——共享
建议:
a. C++编程中不建议使用结构体
b. 所有可以使用枚举定义的常量不建议使用宏定义
c. 类的定义在xxx.h中
d. 成员函数的实现在xxx.cpp中
出拳 (函数)
思考
![]() |
出拳
(属性) 管理2位选手
思考
变量 记录2个比分
函数 宣布比赛结果
(动作) 控制比赛过程
string
姓名
年 变量
(变量) 月 生日
日
:注:函数中的数据不变时,应加const修饰,可以防止数据被修改,也可有利于编译器优化。
构造函数:
Date类测试:
结果:
注:使用new创建对象,在堆中分配内存
特殊数据类型:
cout 数据类型 —— std::ostream
cin 数据类型 —— std::isstream
构造函数 ,是一种特殊的方法(函数) 。主要用来在创建对象时初始化对象, 即为对象成员变量赋初始值,总与new运算符一起使用在创建对象的语句中 。特别的一个类可以有多个构造函数 ,可根据其参数个数的不同或参数类型的不同来区分它们 即构造函数的重载
一般构造函数——自定义的有参或无参构造函数,一个类中可以有一个或多个构造函数(基于C++重载函数)
一般情况下如果自定义类中没有定义任何形式的构造函数,系统会为当前类添加一个无参构造函数,如Date();
复制构造函数——如果当前类中没有定义构造函数,系统会为当前类添加一个默认复制构造函数
如:Date(const Date &date); //参数为当前类的常引用
注:当类中有指针成员时,由系统默认创建该复制构造函数会存在风险,具体原因请查询 有关 “浅拷贝” 、“深拷贝”
引用——实际上就是一个别名
如: int a = 9;
int &b = a; // 声明一个引用,它引用了a,实际上此条语句没有分 配内存,只是给a取了一个别名叫b
b = 4;
a = ? // a = 4
切记:声明引用时,一定要进行直接初始化
常引用——意味着在Date复制构造函数调用时,不会改变date所引用对象的值,只能调用Date类中的末尾带const的成员函数。
示例:void aaa(Date date)
aaa(a);
函数调用时,是实参为形参赋值——Date datel = a;
void bbb(Date &date)
bbb(b);
此时——Date &date2 = b;
date1调用Date类的复制构造函数实例化一个Date对象
date2是一个引用它不调用任何函数,date2作为对象传入到bbb函数中,即意味着bbb函数可以修改b对象(二者除名外,其余完全相同,可以调用b中的所有函数)
基于以上原因,所以函数参数时引用时,多数情况下都写为常引用
原则:右对齐,只能在类定义时写默认值,在函数定义时,不可以写默认值,函数调用时有默认值的形参,可以不传递实参。
如:Date(int nYear, int nMonth = 8, int nDay = 3);
声明:
void setName(string &nName);
void setName1(const string &nName);
调用:
setName(“zhangshan”);
// 错误
setName1(“zhangshan”); // 正确
这两个调用的实参均不是string对象,要在调用时示例化出一个string对象,再调用此时自动实例化的对象是一个常对象
修改:
string n(“zhangshan”); //栈中分配空间
setName(n); // 正确
setName1(n); // 正确
声明:
void setName2(string *nName);
void setName2(const string *nName);
调用:
setName2(new
string(“zhangshan”)); //错误 ??
setName3(new string(“zhangshan”)); //正确
使用const修饰时,*nName不能改变,因此调用时所传的实参,应为一个常量。
注意:使用new string(“zhangshan”)是在堆里分配空间,它返回的是一常指针
修改:
string *n = new string(“zhangshan”); //指针n是在栈中分配空间,指向堆
setName2(n); // 正确
setName3(n); // 正确
申请空间在:
堆——用指针
栈——用引用
函数参数
返回值
成员函数——后加const:代表此函数不修改类内的成员值,即可以通过常引用来调用此函数,如果不写const的同名同参函数与这个带const的函数形成重载,因此通过常引用或常指针调用的birthday函数是带const的,而非常引用或非常指针调用birthday函数是不带const的。
成员函数——前加const:此函数的返回值类型是什么?其const的限定于函数无关,而与函数的返回值有关。
一般情况下,在书写程序时,const一般只与指针、引用还有函数限定这三部分有关
const使用,想要改变以上所说三部分的值时,不加const限定
不想改变时,添加const限定,主要视具体情况而定
定义:函数名相同,但形参的数量或类型不同构成重载
注意:二义性,存在二义性就无法构成重载。如函数调用时,无法区分到底调用哪个函数时,即二义性。
如:构造函数重载
Date(int nYear, int nMonth = 8, int nDay = 3);
Date(int nYear);
这两个函数无法构成重载
const string &Human::name() const与
const string &Human::name() 构成一对重载函数
如:ostream & operator << (ostream &os, const Date &date);
使用:cout<<human.birthday()<<endl;
关键字:operator
构造运算符重载的步骤:
1)知道重载哪个运算符
<<
2)找到操作数类型
ostream Date
3)表达式类型 <<human.birthday()
ostream
4)构造数据类型加&(引用)
5)是否可以const限制
类型 数据
ostream & operator << (ostream &os, const Date &date);
类型 数据
若:
声明:void setName(const string *nName);
定义:Human::setName(const string *nName)
{
n = nName;
}
调用:Human::setName(new string(“zhangshan”));
此用法会导致内存泄露,new string(“zhangshan”)在堆中分配内存,返回的是一个常指针。
原因:delete不能释放一个常指针
注:在使用delete释放任何一个指针后,要赋值为0
delete n;
n = 0;
类定义中
构造函数通常:
string *n = 0;
if(0 == n)
n = new string(“zhangshan”);
析构函数通常:
if(n != 0)
{
delete n;
n = 0;
}
构造函数:
注:子类实例化时,应先构造父类对象
|
public |
protected |
private |
|
public |
protected |
private |
|
protected |
protected |
private |
|
—— |
—— |
—— |
规律:父类中的共有、保护继承后,取权限最低的权限
类内、子类、对象均可访问
类内、子类可访问
类内可访问
枚举可以自动转换为整型,而整型值转换为枚举一定要使用强制类型转换,但使用强制类型转换,一定要注意int的值,是否在枚举的范围内。整型值范围过大,不在范围内强制转换可能会使数据丢失而报错。
多态是指同样的消息被不同类型的对象接收时导致不同的行为。所谓消息是指对类的成员函数的调用,不同行为指不同的实现,也就是调用了不同的函数
体现:
静态—(编译时)—重载
动态—(运行时)—重写
在子类中,定义一个与父类完全相同的成员函数
重写满足三条件——运行过程中的多态
1)类之间满足赋值兼容规则(参数是否对应)
2)要声明为虚函数
3)要由成员函数调用或通过指针、引用来访问虚函数
虚函数是动态绑定的基础,经过派生之后,在类中可以实现运行过程的多态
关键字:virtual
在派生类中,可以不显式给出虚函数的声明,只是对基类中虚函数的重写,此时也可以添加virtual关键字,如MachCompetitor类中的thinkFist()函数。此时派生类中的虚函数便覆盖了基类的虚函数,同时,虚函数还会隐藏基类中同名函数的所有其他重载形式。
注:用派生类对象的指针仍然可以调用基类中被派生类覆盖的成员函数,方法是使用“::”进行限定。如:基类名::函数名()
注意:在重写继承来的虚函数时,如果函数有默认形参值,不要重新定义不同的值。原因:虽然虚函数是动态绑定的,但默认形参时静态绑定的。也就是说,通过一个指向派生类对象的基类指针(简单说,一个指向子类的父类指针),可以访问到派生类的虚函数,但默认的形参值却只能来自基类的定义。
注:C++中,函数、变量的使用都要在一定的域中,全局域可以不加说明
rand()随机函数与随机种子
在不能使用引用时,可以使用指针。???
当前类定义中只使用了Competitor的指针形式,所以此处只需要做类的说明,而不需要类的定义(包含头文件),但需要在.cpp文件中进行头文件包含
优点:当Competitor作任何修改时,当前文件都不需要重新编译,提高整个项目的编译速度。
容器类 |
中文名 |
存储形式 |
用途 |
vector |
向量 |
相当于数组 |
顺序存储或随机或顺序读写 |
list |
列表 |
链表 |
随机存储,顺序读写 |
map |
映射 |
指针数组+动态分配内存 |
以上二者折中 |
vector<T> 对象名(n); //声明一个存储n个T类型的对象
如:vertor<int> vint(8); //分配8个int存储空间
vector<Date> vDate; //只实例化容器对象,不分配存储内存
Map<K, T> 对象名(n);
//K表示键——(特点)唯一,相当于数组下标;T代表类型,相当于数组元素类型
如:map<string, Date> m;
示例:方法一
list<int> vList;
vList.push_back(2); //想列表中添加数据
vList.push_back(5);
vList.push_back(7);
方法二:
list<int>::iterator it; //声明一个迭代器
it = vList.begin(); //将迭代器指向容器首元素
while(it != vList.end())
{
cout<<*it; //*it取迭代器所指向的元素值
*it++;
}
向量可以使用列表方法访问,同时也可以使用下列方法访问
vector <int> vVector(8); //8用于指定向量长度
vVector[0] = 8;
vVector[1] = 4;
vVector[2] = 9;
向量如果实例化时,没有指定向量长度,那么不能使用以上方法为向量存入数据,只能使用push_back和push_
胜——等于1
败——非1或0
平——等于0
(甲-乙):甲胜?乙胜;
甲 |
乙 |
甲-乙 |
甲-乙+2 |
甲-乙+3 |
(甲-乙+3)%3 |
乙-甲+3 |
(乙-甲+3)%3 |
石头 |
石头 |
0 |
2 |
3 |
0 |
3 |
0 |
剪刀 |
-1 |
1 |
2 |
2 |
4 |
1 |
|
布 |
-2 |
0 |
1 |
1 |
5 |
2 |
|
剪刀 |
石头 |
1 |
3 |
4 |
1 |
2 |
2 |
剪刀 |
0 |
2 |
3 |
0 |
3 |
0 |
|
布 |
-1 |
1 |
2 |
2 |
4 |
1 |
|
布 |
石头 |
2 |
4 |
5 |
2 |
1 |
1 |
剪刀 |
1 |
3 |
4 |
1 |
2 |
2 |
|
布 |
0 |
2 |
3 |
0 |
3 |
0 |
将甲、乙两选手的比赛结果进行数据构造
甲:
胜 |
-1 |
-1 |
2 |
败 |
-2 |
1 |
1 |
平 |
0 |
0 |
0 |
胜时为1
因此,使用取模运算,可以实现,取模运算的结果有两种:一种为0, 一种小于被取模的数
a. 在类定义中说明为static,但在类外做函数定义时,不能再说明为static
b. 静态共有成员函数可以直接通过域运算符来访问,即不需要实例化对象
c. 在静态成员函数中,只能使用静态成员变量(静态成员变量对所有对象共享)
d. 静态成员一定要在类外进行初始化
e. 静态成员函数与静态成员变量,常常应用于整个程序调用的一些数据的存储与提取。
定义:关键字inline
inline 类型说明符 函数名(含类型说明的形参表)
{
//语句序列
}
内部机制:编译时,将内联函数以相应代码代替,与宏类似
作用:减少频繁调用小子程序的运行时间开销
内联函数与宏的区别:
a. 内联函数是函数,宏不是
b. 内联函数中不能有复杂的控制语句,如for,switch-case等,适用于1~5行的小函数
a. 下载qt-sdk-linux-x86-opensource-2010.04.bin
b. 赋予qt-sdk-linux-x86-opensource-2010.04.bin包可执行权限
c. 执行该文件 ./ qt-sdk-linux-x86-opensource-2010.04.bin
a. 下载汉化包qtcreator_zh_CN.qm.tar.gz
b. 解压到Qt集成开发环境多语言转换目录
/opt/qtsdk/share/qtcreator/translations/
第一次编译中出现字体库错误,手动添加第三方字体库fontconfig-2.7.3
过程: #./configure
#make
#make install
类名首字母必须大写
当对象改变其状态时,将产生对象。信号就由该对象发射 (emit) 出去,而且对象只负责发送信号,它不知道另一端是谁在接收这个信号。这样就做到了真正的信息封装,能确保对象被当作一个真正的软件组件来使用。
用于接收信号,而且槽只是普通的对象成员函数。一个槽并不知道是否有任何信号与自己相连接。而且对象并不了解具体的通信机制。
1) 信号和槽编辑器
2)控件右键转到槽
3)Qobject::connect
信号 |
连接 |
信号 |
一个信号发射,另一信号跟着发射 |
信号 |
槽 |
|
|
一个信号 |
多个槽 |
调用顺序与连接顺序无关 |
|
多个槽 |
一个槽 |
|
当Qt类想主动向类外传递数据时,需要自定义信号来实现。
元对象编译器(moc)解析一个C++文件中的类声明并且生成初始化元对象的C++代码。元对象包括所有信号和槽函数的名称,还有这些函数的指针。
处理ui图形中的XML代码,生成”ui_xxxxx.h”
资源文件编译器,将文件转化为数据与程序编译到一起,随可执行文件一同发布。好处——资源文件不容易被篡改
中文乱码解决:
Main.cpp 中添加 #include <QTextCodec>
QtextCodec::setCodecForFr(QtextCodec::codecForName(“utf8”));
出现乱码的原因:
String的内部默认编码时unicode,而我们编译器当前的字符编码,可能是GBK或UTF-8
使用网络通信的项目,必须在项目文件中添加:QT += network
棋盘、棋子
使用迭代器遍历向量
封装数据通信套接字
封装监听套接字
网络通信部分:
1)网络数据类型是否分类
a. 聊天信息
b. 用户信息
c. 棋子坐标
2)通信协议制定
数据包长度(quint16) + 数据类型(quint8) + 数据
Qt中父窗口析构,子类也将一同被析构
在设计器中,按钮等上添加&A 相当于快捷方式Alt + A。
资源文件——可支持任意类型的文件
功能:主要针对字符串的处理,如后追加(append)、前添加(prepend)比较(compare)、替换、整型转字符串、
静态共有成员函数:
比较:
int compare ( const QString & s1, const QString & s2, Qt::CaseSensitivity cs )
转格式编码:
QString fromAscii ( const char * str, int size = -1 )
QString fromUtf8 ( const char * str, int size = -1 )
基于本地平台?????
int localeAwareCompare ( const QString & s1, const QString & s2 )
整型转字符串:
QString number ( long n, int base = 10 )
功能:QLabel提供了一个文本或图像的显示的标签,可以设置它的属性,如位置(alignment)、文本(text)、图片(picture、pixmap)
静态共有函数:无
功能:QImage的类提供独立于硬件的图像显示,它允许直接访问的像素数据,并可以作为一个绘制设备。
QImage则是为I/O,为图片像素访问以及修改而设计的。如果你 想访问图片的像素或是修改图片像素,则需要使用QImage
静态共有函数:
QImage fromData ( const uchar * data, int size, const char * format = 0 )
QMatrix trueMatrix ( const QMatrix & matrix, int width, int height )
QTransform trueMatrix ( const QTransform & matrix, int width, int height )
功能:QPixmap是专门为绘图而生,当需要绘制图片时你需要使用Qpixmap
静态共有函数:
自动获取个平台的深度(浓度)
int defaultDepth ()
QPixmap fromImage ( const QImage & image, Qt::ImageConversionFlags flags = Qt::AutoColor )
QPixmap grabWidget ( QWidget * widget, const QRect & rectangle )
QTransform trueMatrix ( const QTransform & matrix, int width, int height )
QMatrix trueMatrix ( const QMatrix & m, int w, int h )
功能:窗口中一行的编辑
静态共有函数:
功能:组合按钮和弹跳列表
静态共有函数:无
功能:旋转窗口部件
静态共有函数:无
功能:消息提示窗口类
静态共有函数:
void about ( QWidget * parent, const QString & title, const QString & text )
void aboutQt ( QWidget * parent, const QString & title = QString() )
StandardButton critical ( QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton )
StandardButton information ( QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton )
StandardButton question ( QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton )
StandardButton warning ( QWidget * parent, const QString & title, const QString & text, StandardButtons buttons = Ok, StandardButton defaultButton = NoButton )
功能:提供一对话框,供用户选择文件或目录
静态共有函数:
QString getExistingDirectory ( QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), Options options = ShowDirsOnly )
QString getOpenFileName ( QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), const QString & filter = QString(), QString * selectedFilter = 0, Options options = 0 )
QStringList getOpenFileNames ( QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), const QString & filter = QString(), QString * selectedFilter = 0, Options options = 0 )
QString getSaveFileName ( QWidget * parent = 0, const QString & caption = QString(), const QString & dir = QString(), const QString & filter = QString(), QString * selectedFilter = 0, Options options = 0 )
功能:将2D图像生成一个坐标系统,进行操作,多用于映射处理,如旋转
静态共有成员:无
功能:实现菜单项、实现工具按钮
信号: 点击——toggled(bool)
选中——activated()
功能:
bootloader |
|
kernel |
rootfs |
userfs |
u-boot环境变量 与部分启动界面
注:PC机中的引导程序为BIOS+ntloader
常用编译器有:
arm-linux-gcc-版本号 |
安装直接解压,路径 添加环境变量 |
/ |
cross-版本号 |
/usr/local/arm |
1)解压
#tar zxvf arm-linux-gcc-4.4.3.tar.gz -C /
2)配置环境变量
打开#vi /etc/profile
添加:export set PATH=$PATH:/opt/FriendlyARM/toolschain/4.4.3/bin
3)测试
#arm-linux-gcc test.c
使用file a.out,查看是不是ARM架构
#file a.out
a.out: ELF 32-bit LSB executable, ARM, version 1 (SYSV), for GNU/Linux 2.6.32, dynamically linked (uses shared libs), not stripped
4)可能出现错误
#arm-linux-gcc a.c
/opt/FriendlyARM/toolschain/4.4.3/libexec/gcc/arm-none-linux-gnueabi/4.4.3/cc1: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by /opt/FriendlyARM/toolschain/4.4.3/lib/libppl_c.so.2)
/opt/FriendlyARM/toolschain/4.4.3/libexec/gcc/arm-none-linux-gnueabi/4.4.3/cc1: /usr/lib/libstdc++.so.6: version `GLIBCXX_3.4.9' not found (required by /opt/FriendlyARM/toolschain/4.4.3/lib/libppl.so.7)
原因:库版本过低,没有GLIBCXX_3.4.9
#strings /usr/lib/libstdc++.so.6 | grep GLIBCXX
GLIBCXX_3.4
GLIBCXX_3.4.1
GLIBCXX_3.4.2
GLIBCXX_3.4.3
GLIBCXX_3.4.4
GLIBCXX_3.4.5
GLIBCXX_3.4.6
GLIBCXX_3.4.7
GLIBCXX_3.4.8
GLIBCXX_FORCE_NEW
解决方法:使用libstdc++.so.6.0.10代替
在/usr/lib/下
#ln –sf libstdc++.so.6 libstdc++.so.6.0.10
机器码——与内核中的机器码必须一致,系统才可启动(可以自定义,但必须一致)
修改开发板相关配置文件include/configs/mini2440.h
//uboot启动后,内核加载的延时
139#define CONFIG_BOOTDELAY 1
//Linux内核引导参数
140 #define CONFIG_BOOTARGS "noinitrd console=ttySAC0,115200
不使用初始启动镜像 标准输入输出定向到串口0
init=/linuxrc root=/dev/nfs nfsroot=192.168.11.11:/work/embedded/rootfs
指定根文件系统 使用绝对路径
ip=192.168.11.22:192.168.11.11:192.168.11.11:255.255.255.0:micro2440.arm9.net
开发板IP 网关 DNSIP 子网掩码 主机名
:eth0:off"
//MAC地址
141 #define CONFIG_ETHADDR 08:08:11:18:12:27
//子网掩码
142 #define CONFIG_NETMASK 255.255.255.0
//开发板IP
143 #define CONFIG_IPADDR 192.168.11.22
//主机IP
144 #define CONFIG_SERVERIP 192.168.11.11
//主机网关
145 #define CONFIG_GATEWAYIP 192.168.11.11
146 #define CONFIG_OVERWRITE_ETHADDR_ONCE
147
148 /*#define CONFIG_BOOTFILE "elinos-lart" */
149 #define CONFIG_BOOTCOMMAND "tftp 0x30007fc0 uImage \; bootm"
命令1 表命令结束 命令2
//bootm 通过uImage引导Linux操作系统
注:当使用zImage引导时,将丢失CONFIG_BOOTCOMMAND配置参数
编译命令:
#make ARCH=arm CROSS_COMPILE=arm-linux- mini2440_config
交叉编译器前缀 配置文件
#make ARCH=arm CROSS_COMPILE=arm-linux- all
tftp——简单的文本传输协议,用于给开发板共享内核以及引导程序重新固化时。
l 修改配置文件/etc/xinetd.d/tftp
service tftp
{
socket_type = dgram #网络类型
protocol = udp
wait = yes
user = root
server = /usr/sbin/in.tftpd
server_args = -s /tftpboot #-s 路径 用于指定服务器共享目录
disable = no #是否禁用此服务
per_source = 11
cps = 100 2
flags = IPv4
}
l 重启服务:
#service xinetd.d restart
l 测试是否成功:
i. 安装tftp客户端,通过系统光盘安装
#mount /dev/cdrom /media/
#rpm -ivh /media/Server/tftp-0.49-2.i386.rpm
ii. 使用tftp命令下载文件测试
#tftp 192.168.11.11
tftp> get test
注:所有用于tftp下载的文件对所有用户都必须至少有可读权限(即444),否则无法下载。
nfs——网络文件系统,用于为开发板共享文件系统,延长flash寿命,提高开发效率。
l 打开配置文件/etc/exports (默认为空文件)
添加
/work/embedded/rootfs *(rw,sync,no_root_squash)
书写格式:
共享目录 共享的目标名或IP(共享参数列表)
每行都是一个共享目录的配置
rw — 读写 sync — C/S数据,同步更新
no_root_squash — 不压制root权限
注:参数之间用逗号分隔,并且逗号两端不能有空格
l 重启服务
#service portmap start
#service nfs restart
l 测试服务
i. 挂载共享文件系统
#mount 192.168.11.11:/work/embedded/rootfs/ /media/
ii. 查看共享目录与挂载目录中,文件是否同步
搭建完开发环境后,对u-boot进行设置,基本操作命令:
tftp 内存地址 文件名
注:地址为一个可用的内存地址,用于临时存放u-boot文件,一般选用0x30008000,我们以明确知道可以的内存地址
1)擦除flash
nand erase 起始地址 长度(单位字节)
注:所以长度单位数值均按字节,使用十六进制数值表示,由于nand flash按页存储,所以长度必须是页的整数倍,页大小为64KB
如:nand erase 0x30008000 200000 //擦除0x30008000后2M的空间
2MB=2048KB=2048*2048Byte=0x200000Byte
2)烧写flash
nand write 内存地址 flash起始地址 长度
3)从nand flash中读取数据到内存
nand read 内存地址 flash起始地址 长度
1)显示环境变量
printenv [变量名]
2)设置环境变量
setenv 变量名 [值]
例:setenv ipaddr 192.168.11.22
注:所设置的环境变量中,有多个值中间由空格或分号隔开时,使用单引号将其括起来。如setenv bootcmd 'nand read 0x30008000 0x200000 0x400000;bootm'
3)保存环境变量
saveenv
1)bootm
使用uImage引导
2)go 内存地址
使用zImage引导
bootargs |
引导参数 |
bootcmd |
引导命令 |
bootdelay |
延时时间(引导程序与加载内核之间的时差) |
ipaddr |
开发板IP |
serverip |
宿主机IP |
gateway |
网关IP |
netmask |
子网掩码 |
eth0addr |
网卡地址 |
baudrate |
波特率 |
(run,autoscr---不是所有uboot必带)
将脚本镜像下载内存
tftp 0x30008000 example.img
运行脚步
autoscr 0x30008000
4. 脚本的生成
工具:
mkimage
位置:
uboot/tools/
命令:
mkimage -A ARM -O linux -T script -C none -a 0 -e 0 -n"example script" -d /home/zhangli/example.script example.img
参数解析:
-A,指定目标映像的体系结构,本实验中是ARM
-O,指定目标映像的操作系统,本实验中是Linux;
-T,指定目标映像的类型,本实验中是脚本;
-C,指定目标映像的压缩类型,脚本不需要压缩,none;
-a,设置U-Boot的加载地址(loadaddress),本实验中设为0;
-e,设置U-Boot映像的入口点(entry point)地址,设为0,即从脚本的起始地方开
始执行;
-n,设置映像的名称;
-d,制作映像的脚本文件
1)修改uboot环境bootargs、bootcmd
setenv bootargs 'root=/dev/mtdblock2 noinitrd console=ttySAC0,115200'
setenv bootcmd 'nand read 0x30008000 0x200000 0x400000;bootm'
参数解析:(参考编译u-boot)
(光盘自带文件系统已存在,自制文件系统暂时未测)
2)生成zImage
make 或makezImage
3)添加内核启动信息
16:23 [root@linfeng boot]#mkimage -n 'linux-2.6' -A arm -O linux -T kernel -C none -a 0x30008000 -e 0x30008040 -d zImage zImage.img
工具:mkimage
参数解析:
-A指定cpu体系结构
-O指定是什么操作系统
-T指定映像类型,如standalone、kernel、ramdisk、multi、firmware、script、filesystem等
-C指定映像压缩方式,如none(不压缩)、gzip、bzip2。这里不对uImage进行压缩
-a指定映象在内存中的加载地址,映象下载到内存中时,要按照用MKIMAGE制作映象时,这个参数所指定的地址值来下载
-e 指定映象运行的入口点地址,这个地址就是-a参数指定的值加上0x40(因为前面有个MKIMAGE添加的0x40个字节的头)
-n 指定映象名
-d 指定制作映象的源文件
4)内核镜像分析
uImage与zImage的区别:
这两个都是内核,zImage是真正的内核,在内存中的地址0x30008000;而uImage是包含64字节头的内核,在头中存放着bootargs环境变量,在内存中的地址0x30007fc0
zImage
0x40
![]() |
![]() |
低地址0 0x30007fc0 0x30008000 高地址
注:当使用zImage引导时,将丢失CONFIG_BOOTCOMMAND配置参数,使用uboot编译时的默认配置参数。
l 内核不断重启
出错信息:
test:starting 1
data abort
pc : [<30008008>] lr : [<31f98ba4>]
sp : 31f5ba94