linux c学习笔记.docx
- 文档编号:30320661
- 上传时间:2023-08-13
- 格式:DOCX
- 页数:71
- 大小:786.07KB
linux c学习笔记.docx
《linux c学习笔记.docx》由会员分享,可在线阅读,更多相关《linux c学习笔记.docx(71页珍藏版)》请在冰豆网上搜索。
linuxc学习笔记
LinuxC学习笔记
1gcc介绍
2gdb工具
gcc–g–oa.debuga.c
gdb
filea.debug
list1查看第一个断点之前的代码
Enter查看之后的断点
Breakx在第x行处加入断点
Infobreakx查看第x个断点的情况
Run运行程序
Next运行下一行
Continue在下一个断点处停下
Step可以进入函数内部运行
3基本类型、转义符、printf、scanf、操作符
4字符处理函数
ctype.h
Stdlib.h
String.h
字符串的比较、复制、连接、查找、替换
Intbcmp(constvoid*s1,constvoid*s2,intn):
比较两个字符串的前n个字节是否相同,相同返回0,不同返回非0.
Intmemcmp(constvoid*s1,constvoid*s2,size_tn):
比较两个字符串的大小是否相同,并且返回第一个不相同字符的差值。
IntStrncasecmp(constvoid*s1,constvoid*s2,size_tn):
忽略大小写比较两个字符串。
Voidbcopy(constvoid*src,void*dest,intn):
复制字符串的前n个字符
Voidmemccpy(void*dest,constvoid*src,intc,size_tn):
同上,可以判断字符串中是否有某一个字符。
Char*strcpy(char*dest,constchar*src)
Char*strncpy(char*dest,constchar*src,size_tn)
Voidbzero(void*s,intn):
字符串清理函数,将字符串中的部分字节写为0,即写入NULL值。
Void*memset(void*s,intc,size_tn):
将字符的前n个字符填充为某个字符。
Char*index(constchar*s,intc)
Char*rindex(constchar*s,intc)
Void*memchr(constvoid*s,intc,size_tn):
在一个字符串的前N个字符中查找某个字符,返回该字符地址。
Char*strchr(constchar*s,intc)
Char*strtchr(constchar*s,intc)
Char*strcat(char*dest,constchar*src):
字符串连接
Char*strtok(char*s,constchar*delim):
将字符串分割成多个字符串,delim是分割标记字符串。
Size_tstrlen(constchar*s)
Size_tstrspn(constchar*s,constchar*accept):
返回一个字符串中首次不包含在指定字符串内容中的字符的位置。
Size_tstrcspn(constchar*s,constchar*reject):
查找一个字符串中不允许出现某个字符的位置。
5时间函数
Time_ttime(time_t*t):
返回时间函数,返回一个时间值,秒数。
Structtm*gmtime(time_t*timep):
取得当前时间
Char*ctime(time_t*timep):
返回字符串形式的字符串
Char*asctime(structtm*timeptr):
返回字符串形式的字符串
Structtm*localtime(time_t*timep):
返回当地时间
Time_tmktime(tm*timeptr):
将tm格式的时间转化成秒数时
Intgettimeoftoday(structtimeval*tv,structtimezone*tz):
微妙级时间返回。
Intsettimeofday(structtimeval*tv,structtimezone*tz):
设置当前系统时间。
6运算符优先表
优先级
运算符
名称或含义
使用形式
结合方向
说明
1
[]
数组下标
数组名[常量表达式]
左到右
()
圆括号
(表达式)/函数名(形参表)
.
成员选择(对象)
对象.成员名
->
成员选择(指针)
对象指针->成员名
2
-
负号运算符
-表达式
右到左
单目运算符
(类型)
强制类型转换
(数据类型)表达式
++
自增运算符
++变量名/变量名++
单目运算符
--
自减运算符
--变量名/变量名--
单目运算符
*
取值运算符
*指针变量
单目运算符
&
取地址运算符
&变量名
单目运算符
!
逻辑非运算符
!
表达式
单目运算符
~
按位取反运算符
~表达式
单目运算符
sizeof
长度运算符
sizeof(表达式)
3
/
除
表达式/表达式
左到右
双目运算符
*
乘
表达式*表达式
双目运算符
%
余数(取模)
整型表达式/整型表达式
双目运算符
4
+
加
表达式+表达式
左到右
双目运算符
-
减
表达式-表达式
双目运算符
5
<<
左移
变量<<表达式
左到右
双目运算符
>>
右移
变量>>表达式
双目运算符
6
>
大于
表达式>表达式
左到右
双目运算符
>=
大于等于
表达式>=表达式
双目运算符
<
小于
表达式<表达式
双目运算符
<=
小于等于
表达式<=表达式
双目运算符
7
==
等于
表达式==表达式
左到右
双目运算符
!
=
不等于
表达式!
=表达式
双目运算符
8
&
按位与
表达式&表达式
左到右
双目运算符
9
^
按位异或
表达式^表达式
左到右
双目运算符
10
|
按位或
表达式|表达式
左到右
双目运算符
11
&&
逻辑与
表达式&&表达式
左到右
双目运算符
12
||
逻辑或
表达式||表达式
左到右
双目运算符
13
?
:
条件运算符
表达式1?
表达式2:
表达式3
右到左
三目运算符
14
=
赋值运算符
变量=表达式
右到左
/=
除后赋值
变量/=表达式
*=
乘后赋值
变量*=表达式
%=
取模后赋值
变量%=表达式
+=
加后赋值
变量+=表达式
-=
减后赋值
变量-=表达式
<<=
左移后赋值
变量<<=表达式
>>=
右移后赋值
变量>>=表达式
&=
按位与后赋值
变量&=表达式
^=
按位异或后赋值
变量^=表达式
|=
按位或后赋值
变量|=表达式
15
逗号运算符
表达式,表达式,…
左到右
从左向右顺序运算
7文件结构体structfile(Linux2.6.23内核)
structfile结构体定义在/linux/include/linux/fs.h(Linux2.6.11内核)中,其原型是:
structfile{
/*
*fu_listbecomesinvalidafterfile_freeiscalledandqueuedvia
*fu_rcuheadforRCUfreeing
*/
union{
structlist_head fu_list;
structrcu_head fu_rcuhead;
}f_u;
structpath f_path;
#definef_dentry f_path.dentry
#definef_vfsmnt f_path.mnt
conststructfile_operations *f_op;
atomic_t f_count;
unsignedint f_flags;
mode_t f_mode;
loff_t f_pos;
structfown_struct f_owner;
unsignedint f_uid,f_gid;
structfile_ra_state f_ra;
unsignedlong f_version;
#ifdefCONFIG_SECURITY
void *f_security;
#endif
/*neededforttydriver,andmaybeothers*/
void *private_data;
#ifdefCONFIG_EPOLL
/*Usedbyfs/eventpoll.ctolinkallthehookstothisfile*/
structlist_head f_ep_links;
spinlock_t f_ep_lock;
#endif/*#ifdefCONFIG_EPOLL*/
structaddress_space *f_mapping;
};
文件结构体代表一个打开的文件,系统中的每个打开的文件在内核空间都有一个关联的structfile。
它由内核在打开文件时创建,并传递给在文件上进行操作的任何函数。
在文件的所有实例都关闭后,内核释放这个数据结构。
在内核创建和驱动源码中,structfile的指针通常被命名为file或filp。
一下是对结构中的每个数据成员的解释:
一、
union{
structlist_headfu_list;
structrcu_headrcuhead;
}f_u;
其中的structlist_head定义在linux/include/linux/list.h中,原型为:
structlist_head{
structlist_head*next,*prev;
};
用于通用文件对象链表的指针。
structrcu_head定义在linux/include/linux/rcupdate.h中,其原型为:
/**
*structrcu_head-callbackstructureforusewithRCU
*@next:
nextupdaterequestsinalist
*@func:
actualupdatefunctiontocallafterthegraceperiod.
*/
structrcu_head{
structrcu_head*next;
void(*func)(structrcu_head*head);
};
RCU(Read-CopyUpdate)是Linux2.6内核中新的锁机制,具体在这里有介绍:
二、
structpath f_path;
被定义在linux/include/linux/namei.h中,其原型为:
structpath{
structvfsmount*mnt;
structdentry*dentry;
};
在早些版本的内核中并没有此结构,而是直接将path的两个数据成员作为structfile的数据成员,
structvfsmount*mnt的作用是指出该文件的已安装的文件系统,
structdentry*dentry是与文件相关的目录项对象。
三、
conststructfile_operations *f_op;
被定义在linux/include/linux/fs.h中,其中包含着与文件关联的操作,如:
loff_t(*llseek)(structfile*,loff_t,int);
ssize_t(*read)(structfile*,char__user*,size_t,loff_t*);
ssize_t(*write)(structfile*,constchar__user*,size_t,loff_t*);
等。
当打开一个文件时,内核就创建一个与该文件相关联的structfile结构,其中的*f_op就指向的是
具体对该文件进行操作的函数。
例如用户调用系统调用read来读取该文件的内容时,那么系统调用read最终会陷入内核调用sys_read函数,而sys_read最终会调用于该文件关联的structfile结构中的f_op->read函数对文件内容进行读取。
四、
atomic_t f_count;
atomic_t被定义为:
typedefstruct{volatileintcounter;}atomic_t;
volatile修饰字段告诉gcc不要对该类型的数据做优化处理,对它的访问都是对内存的访问,而不是对寄存器的访问。
本质是int类型,之所以这样写是让编译器对基于该类型变量的操作进行严格的类型检查。
此处f_count的作用是记录对文件对象的引用计数,也即当前有多少个进程在使用该文件。
五、
unsignedint f_flags;
当打开文件时指定的标志,对应系统调用open的intflags参数。
驱动程序为了支持非阻塞型操作需要检查这个标志。
六、
mode_t f_mode;
对文件的读写模式,对应系统调用open的mod_tmode参数。
如果驱动程序需要这个值,可以直接读取这个字段。
mod_t被定义为:
typedefunsignedint__kernel_mode_t;
typedef__kernel_mode_t mode_t;
七、
loff_t f_pos;
当前的文件指针位置,即文件的读写位置。
loff_t被定义为:
typedeflonglong __kernel_loff_t;
typedef__kernel_loff_t loff_t;
八、
structfown_struct f_owner;
structfown_struct在linux/include/linux/fs.h被定义,原型为:
structfown_struct{
rwlock_tlock; /*protectspid,uid,euidfields*/
structpid*pid; /*pidor-pgrpwhereSIGIOshouldbesent*/
enumpid_typepid_type;/*KindofprocessgroupSIGIOshouldbesentto*/
uid_tuid,euid; /*uid/euidofprocesssettingtheowner*/
intsignum; /*posix.1brtsignaltobedeliveredonIO*/
};
该结构的作用是通过信号进行I/O时间通知的数据。
九、
unsignedint f_uid,f_gid;
标识文件的所有者id,所有者所在组的id.
十、
structfile_ra_state f_ra;
structfile_ra_state结构被定义在/linux/include/linux/fs.h中,原型为:
structfile_ra_state{
pgoff_tstart; /*wherereadaheadstarted*/
unsignedlongsize; /*#ofreadaheadpages*/
unsignedlongasync_size; /*doasynchronousreadaheadwhen
thereareonly#ofpagesahead*/
unsignedlongra_pages; /*Maximumreadaheadwindow*/
unsignedlongmmap_hit; /*Cachehitstatformmapaccesses*/
unsignedlongmmap_miss; /*Cachemissstatformmapaccesses*/
unsignedlongprev_index; /*Cachelastread()position*/
unsignedintprev_offset; /*Offsetwherelastread()endedinapage*/
};
文件预读状态,文件预读算法使用的主要数据结构,当打开一个文件时,f_ra中出了perv_page(默认为-1)和ra_apges(对该文件允许的最大预读量)这两个字段外,其他的所有西端都置为0。
十一、
unsignedlong f_version;
记录文件的版本号,每次使用后都自动递增。
十二、
#ifdefCONFIG_SECURITY
void *f_security;
8memset
需要的头文件
函数原型
void*memset(void*s,intch,unsignedn);memset原型(pleasetype"manmemset"inyourshell)
void*memset(void*s,intc,size_tn);
memset:
作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法。
常见的三种错误
第一:
搞反了c和n的位置.
一定要记住如果要把一个chara[20]清零,一定是memset(a,0,20)
而不是memset(a,20,0)
第二:
过度使用memset,我想这些程序员可能有某种心理阴影,他们惧怕未经初始化的内存,所以他们会写出这样的代码:
charbuffer[20];
memset(buffer,0,sizeof((char)*20));
strcpy(buffer,"123");
这里的memset是多余的.因为这块内存马上就被覆盖了,清零没有意义.
第三:
其实这个错误严格来讲不能算用错memset,但是它经常在使用memset的场合出现
intsome_func(structsomething*a){
…
…
memset(a,0,sizeof(a));
…
}
问:
为何要用memset置零?
memset(&Address,0,sizeof(Address));经常看到这样的用法,其实不用的话,分配数据的时候,剩余的空间也会置零的。
答:
1.如果不清空,可能会在测试当中出现野值。
你做下面的试验看看结果()
charbuf[5];
CStringstr,str1;//memset(buf,0,sizeof(buf));for(inti=0;i<5;i++){str.Format(“%d“,buf[i]);str1+=str;}TRACE(“%s\r\n“,str1)
2.其实不然!
特别是对于字符指针类型的,剩余的部分通常是不会为0的,不妨作一个试验,定义一个字符数组,并输入一串字符,如果不用memset实现清零,使用MessageBox显示出来就会有乱码(0表示NULL,如果有,就默认字符结束,不会输出后面的乱码)
问:
如下demo是可以的,能把数组中的元素值都设置成字符1,
#include
#include
usingnamespacestd;
intmain()
{
chara[5];
memset(a,'1',5);
for(inti=0;i<5;i++)
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- linux c学习笔记 学习 笔记