Linux下c程序开发笔记
第一章1.解释性语言:shell javascript python 编程人员不需要经过编译 连接的过程,可以在特定环境下直接执行的语言 自动编译连接。开发效率高,但运行效率低。编译型语言:java c c++,需要经过编程人员经过编译和连接产生可执行程序的语言。运行效率高。2.数据数据结构:数据之间的一种或多种关系。密切相关的是数据的类型和数据的存放。程序设计:编写程序的过程。软
第一章
1.
解释性语言:shell javascript python 编程人员不需要经过编译 连接的过程,可以在特定环境下直接执行的语言 自动编译连接。开发效率高,但运行效率低。
编译型语言:java c c++,需要经过编程人员经过编译和连接产生可执行程序的语言。运行效率高。
2.
数据
数据结构:数据之间的一种或多种关系。密切相关的是数据的类型和数据的存放。
程序设计:编写程序的过程。
软件:程序和文档。
3.
c语言是结构化的语言
就是说:整个程序是用函数串联起来实现的。功能分解,自顶向下,逐个分解。
第二章
1.
开发环境
编辑器 vi
编译器 gcc
调试器 gdb
函数库 glibc
系统头文件 glibc_header
2.
开发图形界面 图形库
gnome 一般是用c
kde 一般使用c++
3.
IDE 集成开发环境
kylix 号称linux下的dephi
kdevelop
RHIDE 类似与turbo c++
4.gcc
-o 指定可执行文件名
-c 只输出编译结果 不链接,不生成可执行文件
-g 表示在编译时提供以后进行调试的信息
5.glibc 提供系统调用和基本函数的c库
两种安装方式
安装成测试用的函数库
安装成主要c函数库(默认)
几个附加包
linuxThreads locale crypt
6.glibc_header
若果缺少头文件 可以使用rpm的进行安装linux的开发环境
gcc依赖于binutils和app包
7.版本号
ls /lib/libc-* //glibc 版本号
gcc --version
8.c程序组成
可执行文件 最终运行命令
包含文件 include
库文件 该c程序自定义的库
e.g:rpm安装mysql数据库
可执行文件在/usr/bin
包含文件在/usr/include/mysql
库文件在/usr/lib/mysql
只有系统可以找到程序对应的包含文件和库文件,可执行文件才可以执行。
第三章
1.操作系统功能
命令解释
进程管理 进程就是正在运行的程序。分时机制 主要牵涉cpu的管理
内存管理
输入输出操作和外围设备的管理
文件管理
2.linux的特点
具有贵族血统
开发性
多用户
多任务
出色的稳定性和速度性能
丰富的网络性能
可靠的系统安全
可移植性
3.linux 关机
shutdown -h now //关机 推荐 -h可以加时间 表示在多少时间后关机
shutdown -r now //重启 推荐
reboot //快速重启 跳过sync的过程 不推荐 可能造成数据丢失
init 0 //关机
init 6 //重启
halt //系统停机
4.linux系统结构
硬件——kernel(操作硬件,包含很多驱动程序和接口)——shell——外层应用程序
5.linux目录结构
存放命令的目录 /bin 系统工具
/sbin 系统管理员的工具
/usr/bin /usr/sbin /usr/local/bin 普通应用程序的可执行文件 e.g email mysql
/boot 内核及其他系统启动所需的文件
/opt 安装大的应用程序
/tmp 临时文件
/lost+found 系统修复过程中恢复的文件
/root 超级用户的主目录
6. /dev device设备主目录
b-block块设备
c-character字符设备
linux的硬件设备对应文件
/dev/cdrom 光驱设备
/dev/fd0 软驱
e.g:
ls -l 查看设备类型 看看首字符 b c
7. /etc 配置文件所在目录
启动引导程序 /etc/lilo.conf /etc/grub.conf
控制启动模式 /etc/inittab (图形/文本登陆)
文件系统配置 /etc/fstab
/etc/profile 增加环境变量 (修改PATH等) //修改后所有用户都可访问
/etc/ftp* ftp的配置文件
/etc/httpd web服务器的配置文件
/etc/ssh* ssh的配置文件 //比telnet安全
8. /etc/inittab
停止系统
init 0 halt poweroff shutdown
重启系统
init 6 reboot
文字界面启动 init 3
图形界面启动 init 5
单用户模式 init 1 init single //管理员维护时 不允许其他用户登陆
9. /home
用户默认主目录 /home/usrname
useradd username 创建新用户
passwd username 添加密码 //不允许空密码
/etc/passwd:系统能识别的用户的清单
纯文本显示用户名 主目录 启动shell的类型 以及加密的口令 普通用户可读
/etc/shadow:超级用户可读,用于保护加密口令的安全 隐藏口令 较安全
10. /lib 系统所用的库
例如c程序的库
/lib/modules/2.4.20-8/kernel/drivers
驱动模块
/usr/lib 应用程序的库
如mysql的api
11. /mnt
光驱的装载 mount -t iso9660 /dev/cdrom /mnt/cdrom
mount -t 文件类型 设备文件 挂在目录
卸载 umount /mnt/cdrom //不卸载的话,光驱无法打开
软驱的使用 mount -t fstype /dev/fd0 /mnt/floppy
12. /usr 用户目录
/usr/doc /usr/share/doc 帮助文档
man 命令 查看命令的手册页
info 命令 查看命令的帮助
命令 - help
/usr/src/linux-2.4.20-8/ linux的源代码
/usr文件系统部分内容
X11 用于x windows
bin 用户使用的几乎所有的命令程序
sbin 系统管理的命令
include c语言头文件 //c语言头文件的默认存放处
lib 库文件和数据文件
local 本地安装的软件 //放置在local下的文件 在删除linux 时 不会被删除
share 贡献文件和数据
13. /var 变量
www apache的文档目录
lib 系统运行时随时改变的文件
local /usr/local程序的可变程序
log 日志文件
spool 邮件,新闻等队列的脱机目录
tmp 临时文件
14. 了解所用硬盘的信息
mount 所挂载分区 //不常用
fdsik -l [/dev/had] 硬盘分区状况
df -h 硬盘分区的使用情况
du -sh 所在目录占用空间
uname -a 所用linux的版本号
clear 清屏
15. linux常见文件操作命令
mkdir 创建目录
rm -r -f 递归删除目录,并且不显示(y/n)
rmdir 删除空目录
pwd 查看当前目录
cd 切换目录
ls [参数] [路径或文件名]
-a 所有文件
-l 详细信息
-R 递归显示所有目录很文件
-d 不递归
more/less文件:查看文件内容
cat 显示所指文件的内容
mv (move)
mv [参数] <src> <dst>
-I
-f
cp
cp [参数] <src> <dst>
-f force 直接覆盖
-I 提示是否覆盖
-R 递归
16.文件类型
filetype
ordinary files 普通文件(-):文本文件和二进制文件
directory files目录文件(d):文件夹
link 链接文件(l): ln创建的文件
special files 特殊文件: 设备文件(b,c)和管道文件(p)
character device files block device files hard links(可以看成一种复制) symbolic links(相当于windows下的快捷方式)
文件类型对应颜色配置文件:/etc/DIR-COLORS
17.检查文件系统 fsck 修复磁盘
当系统非正常关机,可能无法进入系统,可移植性fsck
fsck [选项] <设备名>
-f fstype 指定要检查文件系统的类型
-N 模拟显示,并不真正检查
-r 恢复时要求用户确认
-p 自动修正安全地更正并且不会导致数据丢失的问题
fsck -p -t ext2 /dev/hda2 //-t可以省略
注:应该先卸载文件系统,在检查
18.文件的查找
find 路径 [选项] //目录先文件的查找
find /etc -name passwd //-name 指定文件名
-size 文件大小查找
-type 文件类型查找
locate
locate -u &
grep [选项] 查找模式 文件名 //文件中查找字符串
grep [参数] ‘str’ filelist
-n 显示匹配的行号
-I 忽略大小写
-r 递归查找
19.索引节点
索引节点是一种结构,包含文件的长度,创建修改的时间,许可权,所属关系,磁盘中的位置等文件信息。
一个文件系统维护了一个索引节点的序列。
每个文件对应唯一的索引节点,而每个索引节点可以对应多个文件
用ln命令创建新的连接,而不复制文件
20.硬链接 符号链接
硬链接:
文件名和链接文件名都指向相同的物理地址
目录不能有硬链接
硬链接不能够跨越文件系统
文件在磁盘中只有一个复制,以节省磁盘空间
防止不必要的误删除(删除文件要在统一节点属于唯一连接是才能成功)
符号链接:
用ln -s命令创建
类似于快捷方式
没有防止误删除的功能(删除文件后,符号链接仍然存在)
查看文件和目录的inode:ls -i
ln [参数] <dst> <link name>
硬链接 ln 源文件 目标文件
符号链接 ln -s 原文件 目标文件
ln -s /usr/local local
21.linux用户类型
root 系统管理员
u 文件拥有者
g 组拥有者
o 其他用户
a 所有用户
rwx rwx rwx
owner group others
rwx r-x ---
111 101 000
7 5 0
e.g:chmod 750 文件/目录名
改变文件的访问权限
符号标记法
chmod (ugoa)(+-=)(rwx) filename/filelist
e.g: chmod g+w o-x /usr/local/*
数字标记法
4读 2写 1执行 0无权限
chown 改变文件或目录所拥有者
chgrp 改变文件或目录所在组
22.文件比较
diff
找出两个文件的差异
diff [] <file><file>
-w 忽略所有空格差别
-I 忽略大小写
cmp //显示的结果比较简单
比较任意两个文件
cmp [] <><>
23.标准文件
标准输入文件
键盘成为标准输入文件
所有打开文件都被赋以一个文件描述符。其中0被赋给标准输出文件。
标准输出文件
监视器为标准输出文件
文件描述符为1
标准错误文件
监视器也是标准错误文件
文件描述符为2
24.重定向
重定向就是改变标准输入输出以及错误的分配
输入重定向 // < 可省略
e.g:cat < test1 <enter>
输出重定向
e.g: cat test1 > test2
错误重定向
e.g: cat datafile 2> error-mesg //错误重定向 用2>
25.网络命令
ifconfig ip 网卡
ping
route -n 查看路由状态
netstat 查看网络状态
26.linux应用软件的分发格式
tar
unix下打包格式 *.tar.gz
rpm
REDHAT公司提供的软件封装格式 *.i386.rpm
dpkg
Debian提供的软件封装格式 *.i386.deb
27.rpm包
rpm -ivh rpm包 安装 //i-install
rpm -Uvh rpm包 升级 //U-update
rpm -e rpm包 删除
rpm -qi rpm包 列出信息 //是否安装 q表示查找 i表示信息
rpm -qf rpm包 'wihch 命令' 显示命令所在包
rpm -ql rpm包 包中的文件列表
www.rpmfind.net
28.备份格式
tar -cvf home.tar /home //c-create v-view f-filename
tar -czvf home.tar.gz /home //z-zip 加压缩
tar -tvf //查看
tar -xvf //解压
tar -xzvf //解压缩包
bzip2 filename -> filename.bz2
bunzip filename.bz2
gzip gunzip
zip unzip
rar
29.技术实验
30.shell 变量
创建变量
可以再任何时间痛过简单赋值来创建
所有变量都被当作字符串
引用变量
$用来引用一个变量的内容
读入值给变量
在执行shell脚本时,允许从键盘输入一个值给变量
read fname //将键盘输入存储到fname
31.本地和全局变量
局部变量
只有创建它的shell能够知道变量的存在,这是缺省
全局变量
又称为子shell
用export特别指出
环境变量
特殊的全局变量
用来定制环境
HOME PATH PS1 PS2 LOGNAME SHLVL SHELL
e.g:
HOME
每个用户都有一个相关的HOME目录
PATH变量
用冒号定界的目录名称,便于可执行程序的搜索
PS1
prompt string 1 包含shell提示符
PS2
第二个提示符
LOGNAME
包含用户的注册名字
SHLVL
由于可以再shell再次打开别的shell,这个可以用来查看在第几个shell
SHELL
缺省shell
env命令
查看现在的所有环境变量的值
32.命令替换
在单个命令中使用多个命令的另一中方法(不是管道)
e.g:echo "the date is `date`"
expr命令
用于求值算术表达式
e.g:expr 4 + 5 注意空格,否则当作字符串
算术展开
用$((...)) //这时不会当作字符串
e.g:
pending=$((totalcalls-answered))
33.条件执行
test和[]命令
求表达式的值,并返回true(0)或false
if构造
提供循环和判定
算术测试
结合if构造,用于测试变量的数字值
字符串测试
test命令可以用于
文件测试
test命令可以检查文件的状态
exit命令
用于终止shell脚本的执行并返回到$提示符下
34.test测试命令1
数值测试
-eq 等于为真
-ne 不等于为真
-gt 大于为真
-ge 大于等于为真
-lt 小于为真
-le 小于等于为真
35.test测试命令2
字符串测试
= 等于为真
!= 不等于为真
-z字符串:字符串长度为零则为真
-n字符串:字符串长度不为零则为真
36.test测试命令3
文件的测试
-e文件名 文件存在为真
-r文件名 存在并且可读为真
-w文件名 存在并且可写为真
-x文件名 存在并且可执行为真
-s文件名 文件存在并且至少有一个字符为真
-d文件名 文件存在并且为目录为真
-f文件名 文件存在并且为普通文件为真
-c文件名 文件存在并且为字符型特殊文件为真
-b文件名 文件存在并且为块特殊文件为真
-a并且 //and
-o或者 //or
! 非
test $* -le 80
[ $* -le 80 ]
37.case...esac构造
用于这个结构依据变量的值,执行一组特定命令
结构中选项是以;;结尾
*)相当于default选项
echo -n "..." //表示输出后不换行
38.迭代
while构造
while<>
do
<命令>
done
只有条件为真时才会执行do与done之间的命令
until构造
until的求值模式与while相反,先执行一次循环体,最少执行一次
for构造
for var in <list of values>
do
...
done
for循环取一列值作为输入并对循环中每个值进行循环
break 终止循环
continue 强迫一个新的循环的开始,回到循环初始
39.控制进程的执行
请求后台处理
&
e.g: wc tempfile &
检查后台进程
ps
可以查看进程号
终止后台进程
kill 进程号
查看完成一个命令所花的时间
time 命令
e.g: time find /etc -name "passwd" 2> /dev/null //错误信息重定向到空设备/dev/null 就是忽略掉
40.管道
|
管道之前的输出作为管道之后的输入
41.
vi /etc/profile
增加
PATH=$PATH:.
export PATH
此种方法需要重启
或者
在$提示符下,PATH=$PATH:.
42.
expr 4 + 5
expr "4" + "5"
echo $((4+5))
echo $(( 4 + 5 ))
以上都是用来求4+5,结果相同
43.
echo "Name:$name Email:$email">>*.txt //文件内容是追加的
第四章 vi编辑器的使用
1.输入模式命令
i 在光标前输入文本
I 在当前行开始输入文本
a 在光标前输入文本
A 在当前行末尾输入文本
o 在当前行后输入一行
O 在当前行前输入一行
2.光标移动 //暂不推荐
b 移动到当前单词开始
e 移动到当前单词结尾
w 向前移动一个单词
h 向前移动一个字符
j 向上移动一行
k 向下移动一行
l 向后移动一个字符
3.删除操作
x 删除光标所在字符
dw 删除光标所在单词
d$ 删除光标至行尾所有字符
D 同上
dd 删除当前行
4.改变与替换操作
r 替换光标所在字符
R 替换字符序列
cw 替换一个单词 //c-change
ce 同上
cb 替换光标所在的前一个字符
c$ 替换光标位置到行尾的所有字符 //$就是表示行尾
C 同上
cc 提换当前行
5.查询命令
/abc 向前查询abc //在最后行模式输入
?abc 向后查询abc
n 向前继续查询
N 向后继续查询
6.拷贝粘贴
yw 当前光标单词拷贝到剪贴板
y$ 将光标至行尾的字符拷贝到剪贴板
Y 同上
yy 当前行考入剪贴板
p 将剪贴板的内容粘贴在光标后
P 将剪贴版中的内容粘贴在光标后
//3yy 将从当前行起三行拷贝到剪贴板
7.文件保存
:w! filename 强制存入
:x 同:wq
zz 同:wq,但是在命令模式,而不是最后行模式
8.其他命令
:set nu 显示行号
在命令模式下用nG 跳到n行
U 撤销
. 重做 redo
nyy 拷贝n行
:e filename 创建新文件
:n filename 加载新文件
:!gcc 不需要推出,直接在vi下编译文件
:!ls 不需要推出,直接在vi下ls
第五章 基本数据类型与表达式
1.c语言字符集
(1)英文字母:大小写26个,共52
(2)十个数字
(3)下划线 分号
(4)特殊符号 一般来表示运算符
算术运算符
关系运算符
逻辑运算符
位运算符
条件运算符 ?:
赋值预算符
其他分隔符
2.标识符 (变量、函数、文件的名字)
a.只能是字母 数字 下划线组成,第一个字符只能是字符或下划线
b.大小写敏感
c.关键字保留
3.关键字
ansi推荐32个,与数据类型有关14个,存储类别 4个,与程序控制相关 12个
4.常量和变量
八进制形式:在数字前加数字0
e.g:012=10 十进制 ,因此不要随意在数字前加0
十六进制:在数字前加0x 大小写都可以
注意:
小数点不能单独出现,但0. .0 都可出现
e或E前后必须有数据,并且后边必须为整数
/ddd 8进制表示的ascii码对应的一个字符
/xhh 16进制表示的ascii码对应的一个字符
如何显示单引号 '/''
双引号 '/"'
5.字符的值域
ascii字符表中的字符,占用一个字节,包括可显示字符和非显示的字符
6.符号常量
#define 标识符 常量数据
e.g: define pi 3.14159
7.整型变量(一般情况下)
int 2个字节
long 4个字节
常量中无unsigned型
但是一个非负的整常量可以赋值给unsigned型变量,只要它的范围不超过变量表示的范围
数据后将一个字母l货L,就表示是长整型的
8.实型变量
float 4个字节
double 8个字节
long double 16个字节
9.字符变量
char 1个字节
10.变量初始化
变量定义 分配存储空间
变量初始化 分配空间同时存入数据 //初始化不能用连等号
11.
printf("s=%8.4f",s) //表示共输出8位字符,小数点后4位
12.逻辑量的真假
整型 0
实型 0.0
字符型 /0
指针型 null
e.g:
a&&b&&c
只有a为真,才判断b,只有b为真才判断c
如果a为假,那么不会判断后边的值
exp:
a=0;b=1;c=2;
d=a++&&b++&&--c
首先判断a=0,那么整个d=0,不会计算后面的值
随后 a+1,
b,c由于没有运算,进而不会改变
这种叫做快速与
相似的快速或 a||b||c
13.优先级
e.g:
1.x=(y=12)/4 //y=12后 返回12
y=12 x=3
2.x=y=12/4
x=y=3
3.x=(y=12/4)
x=y=3
4.(x=y)=12/4 //这是错误的 由于第二个等号左边是表达式而不是变量
14.符合赋值运算
a*=b+c 相当于a=a*(b+c) //这个要注意
y=x>10?x/10:x>0?x:-x; //结合性自右至左
15.求字节运算符
sizeof 变量名
sizeof (类型名)
16.类型隐形转化
int和float都会自动转换为double
但是int不会转换为float型
赋值右边的类型会转换为左边类型一致的值
e.g:
实型赋给整型,去掉小数部分
整型、字符型赋给实型,补足有效位
17.强制转换
e.g:
int a=2,b=5;
(float)b/a 2.5 //现将b转换为5.0,再进行计算
(float)(b/a) 2.0
第六章 顺序程序设计
1.局部变量会覆盖全局变量的值,但是跳出大括号,则局部变量失效。每一条执行语句,会先找量的值,不论局部还是全局,如果只有全局就得到全局值;如果是局部值,和全局值都有就用局部值。
标准输入输出
2.getchar
int getchar(void);
从标准输入设备(一般是键盘)读入一个字符,并且返回这个字符的ascii码值,并且将敲入的字符回显在屏幕上
一次性输入字符串,直到按回车键
英文 标点 数字 均作为 字符输入 //回车 tab也是
3.putchar
int putchar(int)
向标准输出设备(显示器)输出一个字符,并返回输出字符的acsii码值
putchar(65+1) //输出B,由于输出的是字符
格式输入输出
4.printf (char *format[, , ,...])
执行出错,则返回非零值
printf("格式控制字符串",输出型列表);//这里是英文的双引号
格式字符控制
普通字符:按原样输出 a=%d
转义字符:指明特定操作 /t
格式说明:%c 输出字符
%[flags][width][.prcc][F|N|h|L][type]
flags:- 左对齐 缺省右对齐
+ 正数带加号 负数带减号
空格 正数不带加号 负数输出减号
e.g:%+d %-d % d
width:十进制整数 指定输出宽度
指定宽度》实际宽度 补空格
指定宽度《实际宽度 按实际输出
缺省是按照实际输出
e.g:%+10d
.prcc:输出精度指示符
对于整数,表示至少输出的小数的个数
对于实数,表示至多输出的小数的个数,不足补零,多则舍入
对于字符,最多输出字符的个数,不足补空格,多则丢掉
FNhL:输出长度的修饰符
F输出远指针存放地址
N输出近指针存放地址
H或h输出短整型数据
L或l输出长整型或双精度值
type格式字符
用来进行类型转换
%d十进制输出正数
%o八进制无符号输出整数,不输出前导零
%x十六进制无符号输出整数,不输出前导符0x
%u无符号十进制输出整数
%c输出一个字符
%s输出字符串
%f以小数形式输出单双精度数,默认小数6位
%e以指数形式输出,默认小数6位
%g由给定的值自动选取%f %e
%%输出%
e.g:printf("%d/t%d/t%d/n",++i,--i,i--);//整个式子计算方向,从右至左
结果是:7 6 8 //需验证
int a=3,b=4;
printf("%d/n",(a=b,b,a+3)); // 7 按照逗号表达式顺序输出
printf("%d/n",a=b,b,a+3); // 4 对应左边第一参数的值
5.int scanf (char *format [, argument,..]);
从键盘输入若干任何类型的数据给argument所指的单元//注意不同元素的输入用enter或空格隔开,进而不能输入带有空格的字符
返回读入并赋给argument的数据个数
遇文件结束返回eof,出错返回0
scanf("格式控制字符串",地址列表);//一般来数,一个%对应一个地址
格式控制字符
普通字符:原样输入
个数说明:%[*][width][F|N][h|l]type
*:输入赋值抑制字符 要求输入数据但是不赋值,即在地址列表中没有对应的地址项
width表示宽度
F|N:表示远近指针
h|l数据输入类型
type必须的格式字符,表示数据转换后的类型
d|D 用十进制输入
o|O 八进制
X|X 十六进制
i|I 无开头对应十进制,0开头对应八进制,0x开头对应十六进制
u|U 输入无符号十进制
c 输入单个字符
s 输入字符串,送入字符数组
f|e 用来输入实数,用小数或指数形式输入
g|G 和f作用相同
n 不输入数据,只将该语句已成功读入的字符数(截止到%n)送到对应地址
% 输入%
e.g:scanf("i=%d",&1);
scanf("%d%d%d",&a,&b,&c); //输入时用enter或者空格分割,并且注意输入结尾不需要/n换行
//注意scanf在输出的变量前有&,而printf在输出变量前没有
注意:scanf的格式控制字符串中没有转义字符 e.g:scanf("%d/n",&a);///n是错误的 切忌
其格式控制符是用来输入的,而不是显示的
pow(r,2);//r的平方
第七章 选择程序设计
第八章 循环程序设计
1.在用循环计算时,要考虑算法。在不能考虑资源的情况下的循环(时间和空间度),往往是很荒谬的
1+2+3...+1000
用for循环,是一种耗费时间的算法
用一个=时间复杂度就小很多了
2.循环的省略形式
while(putchar(getchar())!='.');
第九章 数组
1.一维数组
数组是有序数据的集合。
2.static型数组,如果没有进行初始化,默认为0;字符型默认为"/0"//ascii码为零的字符
auto型数组,不进行数组初始化,编译器不自动赋值,这个值是不可知的。 //没有加static的数组 默认为auto型
3.二维数组
float a[3][4]; //表示a包含三个小数组,每个小数组包含4个元素
其在内存中的存放情况为 a[0][0],a[0][1],a[0][2],a[0][3],a[1][0]...a[2][3]
static int a [3][4]={{,1},{0,6},{0,0,1,1}}; //结果是0100 0600 0011
4.字符串处理函数//与scanf不同,可以包含空格的字符串输入,分割以 enter为边界
#include "string.h"
字符串拷贝函数char *strcpy (char *dest,const char *src);
将src复制到字符数组dest,返回被复制的字符串
src可以是字符数组名、字符串常量、字符指针变量
dest可以是字符数组名或者字符指针变量;若dest是字符指针变量,注意给该指针变量赋初值
dest长度》=src长度,避免丢失
字符串结尾是以/0结尾,那么遇到/0,就表示字符串结束
字符串连接功能char *strcat(char *dest, const char *src);
将src字符串连接在dest尾部,并且删除src的/0,返回连接以后的字符串
字符串长度计算函数unsigned int strlen(const char *str);
求出字符串或字符数组中的实际个数,不计算/0,遇到第一个/0就停止计算
字符串的比较函数int strcmp(const char *s1, const char *s2);
从左到右比较各个字符的ascii码,知道遇到不同值或结束标记
返回值 0 字符串相同
负整数 串1《串2
正整数 串》串2
e.g: strcmp("d","abc"); //由于d》a,ascii码,所以返回正整数
第十章 模块化设计与函数
1.模块和函数
各模块可单独设计,然后讲求解所有子问题的模块组合求解原问题。
自顶向下的设计:大问题化成小问题
模块设计:高内聚 低耦合
2.有参函数 无参函数 空函数
3.形参在调用时才被分配内存,函数执行完毕,形参的内存被释放
形参和实参之间的关系:单向的值传递
4.递归调用:自己调用自己
直接调用:e.g:void a(){……a()……}
间接调用:几个函数互相调用
e.g:计算n!
#include <stdio.h>
long fac(unsiged n)
{
long f;
if(n=0)
f=1;
else
f=n*fac(n-1);
return f;
}
5.局部变量的优先级>全局变量的优先级
6.static 静态存储变量:生存期为程序执行的整个周期。
7.存储特性
auto自动型
static静态型//不论是加在局部变量还是全局变量都会长期占用内存
register寄存器型//使用频率很高的变量,提高运行速度
寄存器变量只限于整型、字符型、指针型变量
寄存器变量是动态变量,允许说明两个寄存器变量
extern外部型//本模块文件用另一个模块文件的全局变量,要用extern说明
这种变量在定义是分配内存,而extern时,不会分配内存
但注意要include另一个模块文件,否则找不到
第十一章 预处理命令
1.编译预处理
作用域 自从出现点到原程序结束
2.三种预处理命令
执行宏定义(宏替换) define
包含文件 include
条件编译
3.宏定义
#define 宏名 串
e.g:#define PI 3.14159
#undef终止宏定义的作用域:
e.g:#undef PI //之后宏定义失效
e.g:#define R 3.0
#define PI 3.1415926
#define L 2*PI*R
//注意""内的宏不会展开
4.带参数的宏定义
#define 宏名(参数表) 字符串
e.g:#define S(a,b) a*b
5.宏和函数的区别
预处理只占编译时间,不占用运行时间;函数占用运行时间
引用宏没有返回值
6.文件包含#include
<>:在标准头文件目录/usr/include
"":在当前目录下
7.常量表达式的条件编译
形式一:#if 常量表达式//表达式非零值时 执行程序段
程序段
#endif
形式二:#if 常量表达式
程序段1
#else
程序段2
#endif
形式三:#if 常量表达式1
程序段1
#elif 常量表达式2
程序段2
#else
程序段3
#endif
8.定义标识符的条件编译
形式1:#ifdef 标识符 //之前已定义标识符 则执行程序段
程序段
#endif
形式2:#ifdef 标识符
程序段1
#else
程序段2
#endif
形式3:#ifndef 标识符 //之前没有定义标识符 则执行程序段
程序段1
#else
程序段2
#endif
9.e.g:
#define squ1(a,b) a*b
printf("%f/n",24.0/squ1(1+2,2+3));//替换为24/1+2*2+3=31,注意不是24/(1+2)*(2+3),只是替换,不考虑结合律
第十二章 指针的用法
1.变量pointer为指针变量,存储另一个变量的地址。
指针与指针变量的区别就是变量值和变量的区别。
2.指针变量的三个要素
类型:和所指变量的类型一致
值:另一个变量在内存中的地址
名字:规则同普通变量
3.赋值的方式
e.g: int i,*p,*q;
p=&i; //方式一
q=p; //方式二
4.指针算术运算
P++ //增加p所指向类型所占的字节数 如果p指向int P++后 相当于P+2(一般情况);p指向float,相当于P+4
5.指针比较运算
6.指针的指针
指向指针的指针
e.g:int i,*p,**q;
i=30;
p=&i;
q=&p;
7.指针变量可作为函数参数
8.指针函数
返回一个指针
e.g:int *func(int,int) //返回一个整形指针
{......}
9.指向函数的指针
函数名 就是函数的入口地址
指向函数的指针定义方式 e.g:int (*p)();可以将函数名直接赋给p e.g:p=max;//max是函数名
那么函数调用时可以 (*p)(a,b) //如果函数原型为max(int,int)
10. p=p+1 新p指向数组下一个元素,也就是移动d个字节 d是一个元素所占的字节
11.引用数组元素的两种方式
下标法a[i]
指针法*(a+i)
注意:int a[10],*p;
p=a;
p++合法,a++不合法;//a是常量不能++
时刻注意指针变量的当前值
e.g:p=a
for(i=0;1<10;i++)
scanf("%d",p++); //由于p是指针,所以没有&
p=a; //特别注意,如果没有这句,将输出不确定的内容
for(i=0;1<10;i++)
printf("%d",p++);
12.x=*p++ *与++同级 等价于x赋值为a[0],p再指向a[1]
*(p++) 先取*p值,后p+1 与上同 //注意先使用p
*(++p)先p+1,后取*p的值
(*P)++ 表示p所指向的元素值+1
13.多维数组的指针
int a[3][4]
a a[0]+1 a[0]+2 a[0]+3
a+1
a+2
数列相当于三个小数组
对于多维数组 int a[3][4],*p=a,*q=a[0];
p和q代表意义有所不同???
p是代表二维数组第0行首地址
q代表第0行第0列元素地址
a+1或者q+1代表第1行首地址
14.指针和字符串
char *p ="I love china "; //这是初始化,指针p指向I 的 地址 ,也就是串首
第十三章 结构体和共同体
1.结构体类型的定义
struct 结构体名
{
类型标识符 成员名1;
……
}; //这个;不能少
e.g:
struct student
{
char name[20];
char sex;
int age;
float score;
char addr[30];
};
2.结构体类型变量的定义
方法1:在定义了结构体类型之后(如上),在定义变量名
struct student stu1,stu2;
方法2:在定义类型同时定义变量
struct 结构体名
{
成员列表
}变量名列表;
e.g:
struct student
{
int num;
char name[20];
char sex;
int age;
float score;
}stu1,stu2;
方法3:直接定义结构类型的变量
struct
{
成员列表
}变量名列表;
//变量可以使用,但是结构体类型在别的地方 不可用,不推荐
3.结构体类型的嵌套
struct date
{
int month;
int day;
int year;
};
struct student
{
char name[20];
char sex;
int age;
struct date birthday;
};
4.结构体变量的引用 结构体变量名.成员名 // 其中.的运算级最高
初始化时,必须是对各个成员进行赋值 //初始化可用.运算符
但是可以用变量名直接整体引用 //nextday=today 其中today成员已赋值,整体赋给另一个结构体变量
初始化方法2:定义时放入“{ }”中
struct student
{
char name[20];
char sex;
int age;
float score;
}stu2={"007",'m',20,88.5};
5.结构体数组变量
struct student
{
char name[20];
char sex;
int age;
struct date birthday;
}stu[30];
注意:如果这时 结构体变量指针p指向stu,那么p+1指向stu[1]
e.g:
struct student
{
char name[20];
char sex;
int age;
struct date birthday;
}stu[3]={{...},{...},{...}};
scanf("%d",&num);
for(i=0;i<num;i++)???????????????????????????????????????????
6.结构体和指针
指向结构体变量的指针 struct student stu1,*pst;
pst=&stu1;
运用 stu1.num=1001;
(*pst).num=1001;
pst->num=1001;
特别注意:pst不能指向成员 pst=&stu1.num 错误
但是如果是 int *q; q=&stu1.num 可以
7.共用体 //特殊的结构体,很多特性与结构体相似
使几个不同的变量占用同一段内存空间的结构
union 共同体类型名
{成员列表;};//最长的成员所占内存空间大小为这个共用体的内存大小
union [data]
{
int i;
char ch;
float f;
}un1,un2,un3;
共用变量的定义:
间接定义:先定义类型,在定义变量
直接定义:定义类型的同是定义变量
8.共用体特点
某一时刻,存放的和起作用的是最后一次存入的成员值。//采用覆盖技术
由于所有成员共用统一内存地址,共用变量与其各个成员的地址相同
&un1=&un1.i=&un1.ch=&un1.f
不能对共用变量进行初始化
不能将共用变量作为函数参数
函数也不能返回一个共用数据
但可以使用指向共用变量的指针
共用类型可以出现在结构体类型中,反之也可以
9.枚举型
枚举类型定义
enum 枚举类型名 {取值表};
e.g:
enum weekdays {sun,mon,tue,...};
枚举变量的定义
间接定义:enum weekdays workday;
直接定义:enum [weekdays] {sun.mon,tue,...}workday;
说明:适用于取值有限的数据
枚举元素其含义由程序解释
初始化 有自加一的特性
10.type定义类型
用typedef定义已有类型的别名
e.g:typedef float real;
typedef struct date {...} Date;
注意typedef是在编译时处理;#define是在编译前的编译预处理是处理的,而且只是做简单的字符替换。
11.位段结构
存储信息时,有时1个信息不需要占用一个字节,只需要一个位就行。
位段结构:所有成员均以二进制为单位来定义长度,并且称成员为位段。
e.g:
struct status
{
unsigned sign: 1;
unsigned zero: 1;
unsigned carry: 1;
unsigned parity: 1;
unsigned half_carry: 1;
unsigned negative: 1;
}flags;
说明:
赋值、引用与结构变量相似
取值空间:长度为n,其取值范围0-(2en)-1
无名位段:长度为0,则为标示位,标示后面的位段在下一字节存储
1个位段必须存储在1个存储单元。如果本单元不能容纳,则从下一个单元开始存储。
可以用%d,%x,%u,%o等格式字符,以整型形式输出位段
引用位段时,系统自动将位段转化为整型数
更多推荐
所有评论(0)