栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

《Linux 高级编程》

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

《Linux 高级编程》

文章目录
    • linux 常用工具简介:
      • tar打包器---解压缩指令:
      • 常用命令:
      • 可执行文件查看(代码段,数据段,bss段):
      • 堆和栈的区别:
    • 常见内存错误说明:
    • 内存分配相关理解:
      • 1.内存分配方式:
      • 2.动态分配常用函数及说明:
        • 2.1 malloc & free:
        • 2.2 realloc:
        • 2.3 calloc():
        • 2.4 alloca ():
      • 3 内存常用管理函数:
        • 3.1 memcpy():
        • 3.2 memmove():
        • 3.3 memset():
        • 3.4 memchr()
        • 3.5 memcmp():
    • 文件与文件流及相关操作函数:
      • 1.文件存储及操作分类:
      • 2.标准流及流主要功能:
      • 3.文件流指针:
      • 4.缓冲区类型及指定:
        • 4.1缓冲区分类:
        • 4.2 缓冲区指定函数:
      • 5 ANSI C文件I/O操作:
        • 5.1 fopen()打开文件:
        • 5.2 关闭文件fclose() /fcloseall():
        • 5.3 更新缓冲区内容fflush:
        • 5.4 字符读操作:
        • 5.5 字符写操作,标准流中写一个字符:
        • 5.6 行读出操作:
        • 5.7 行写入操作:
        • 5.8 块读出操作:
        • 5.9 块写入操作:
        • 5.10 feof() 文件末尾检测函数:
        • 5.11 ferror() 函数判断给定流是否错误:
        • 5.12 clearerr() 清除错误标识位
        • 5.13 ftell() 返回当前读写位置:
        • 5.14 fseek() 修改当前读写位置。
        • 5.15 rewind() 重置当前读写位置

《Linux 高级程序设计》

  • UNIX 操作系统于1969 年在AT&T贝尔实验室实现。收取少量费用供其它开发者使用修改。

  • 加州大学伯克利分校计算机系统研究小组CSRG 借助UNIX 对操作系统研究,改进,包括撰写更好的内存管理等,组成完整的BSD-UNIX 系统向外发行。

  • Linux 由操纵系统发展而来,由Linux Torvalds 和网络黑客从0编写。是一套开源代码,但遵循GNU 的GPL.(因为不限制商家对自由软件进一步开发,因此出现ubutu, redhat 等多个linux发行版)

  • GUN 项目开发很多高质量编程工具(如emacs,gcc,g++),所有GNU软件和派生工作均使用GNU 通用公共许可证(GPL)。

  • posix 标准表示可移植操作系统接口,不局限于UNIX 。posix 提供源代码级别的C语言应用编程接口,如read/write. posix 1.0 和 posix2.0 分别定义了兼容操作系统的C语言系统接口以及工具标准。

  • 库函数和系统调用:库函数完成常见功能,系统调用通常与操纵系统有关,库函数最终一般还是会调用系统函数。系统函数会从用户模式切换为内核模式,然后使用系统资源。

  • glibc 函数库:c语言并没有为常见的操作,如输入/输出,内存管理等提供内置支持。这些功能一般由标准函数库来提供。GNU 的函数库glibc 是Linxu 最重要的函数库,定义ISOC 标准所有库函数以及posix附加特色及GNU其他扩展。

  • 在线文档查询: 命令行man xxx, 工具软件则是用info(m/n/p/q 等指令).

  • 获取错误信息方法:当系统调用出错时会返回-1, 错误信息记载在全局errno 中。 有关errno定义在/usr/include/asm/errno.h 中。

    ERERM0 :没有操作权限
    ENOENT1:文件或目录不存在
    ESRCH3:没有此程序
    EINTR4:系统调用中断
    EI05:I/0错误

    错误打印输出函数,一般使用perror(“hxg”); 后面自动会将错误信息打印输出。也可以使用strerror 将错误打印到标准输出。

linux 常用工具简介: tar打包器—解压缩指令:

解压缩指令:

  • tar -cvf filename.tar xxxfile //将xxxfile 打包成filename.tar
  • tar -xvf filename.tar //解压打包文件
  • tar -cjvf filename.tar.bz2 xxxfile //将xxx file 用bz2 压缩并打包
  • tar -xjvf filename.tar.bz2 //强filename.tar.bz2 解压缩
  • tar -czvf filename.tar.gz directory/file 将file用gzip压缩并打包
  • tart -xzvf filename.tar.gz //解压一个gzip格式的Tar 文件。
常用命令:
  1. expand 如expand -t 4 hello.c 将hello.c 的制表符设置为4个空格
  2. grep 搜索字符串
    1. -i: 不区分大小写
    2. -I:只首次匹配
    3. -n: 输出前加匹配串所在行的行号
  3. find 查找文件
可执行文件查看(代码段,数据段,bss段):

gcc -o test hello.c

$: ls test -l 查看文件test的属性

$: file test 列出ELF 格式; ELF 格式可执行文件存储时分为代码区(text),数据区(data)和未初始化数据区bss 3个部分。 也可以readelf -a test 读取test 详细的elf 信息。

  • 代码区:CPU可执行的指令,通常为只读。被const声明的变量以及字符串常量在代码段中申请空间。
  • 数据段:已被初始化的全局变量或已初始化的静态变量(静态全局变量和静态局部变量),或者数据常量。
  • BSS 区(未初始化的数据区):未初始化的全局变量和静态变量。
  • 局部变量是运行中在栈中分配。
堆和栈的区别:
  • 管理方式不同:栈操作由系统自动管理完成,而堆工作由程序员管理控制
  • 空间大小不同:系统预先设定栈顶和大小,当申请空间超出栈剩余空间时,将出现栈溢出错误。堆是向搞地质扩展,不连续的内存。
  • 产生碎片不同:频繁使用malloc、free 会产生大量碎片,使得程序效率降低。
  • 分配方式不同:堆由malloc 和free 分配释放,而栈动态分配有alloca() 完成且其由编译器自动申请和方式,无需手工。
  • 分配效率不同: 堆分配效率较低。
常见内存错误说明:
  • 拒绝返回局部变量地址。
  • 操作系统加载某个应用程序时,分配一定大小的栈空间。避免申请过大局部变量以出现栈溢出。
  • 动态内存管理常见错误:
    • 申请和释放函数不一致! 使用C申请就是用C释放,使用C++申请就使用C++释放
    • 申请和释放大小不一致! 申请多少就释放多少
    • 释放后仍然读写! 释放后内存不应再读写。
内存分配相关理解: 1.内存分配方式:
  • 静态分配:编译器在编译源代码时分配,如全局和静态变量。程序执行前分配,效率高。可直接使用变量名字操作。
  • 动态分配:程序执行时调用malloc() 库函数申请。程序执行时分配,效率低。使用指向内存的指针是使用动态内存的唯一方法。
2.动态分配常用函数及说明: 2.1 malloc & free:

说明:

  • malloc()分配连续存储的空间,返回该空间的首地址;当剩余空间不足时,返回NULL

  • free()与malloc()配套使用,用于释放malloc分配的内存。

特点:

  • malloc 分配的内存使用完需要使用free释放
  • 不要使用free释放非malloc 分配的内存
  • 内存首地址返回的指针不要进行加减操作再free,否则会引发问题
  • 不能两次释放相同的指针
  • 内存释放后,指向内存的指针应该被赋值为NULL。
2.2 realloc:

说明:

  • 在堆中更改已经分配的内存空间。extern void *realloc(void *ptr,size_t size);

特点:

  • 当前内存段后面拥有足够内存空间则直接扩展这段内存空间,返回原指针
  • 如果当前内存段后空闲字节不够,就重新寻找满足的内存块,并将目前数据copy到新位置,原始数据块释放(即释放原来指针realloc()的参数指针),返回新内存块地址。
  • 如果申请失败,则返回NULL.
2.3 calloc():

说明:

  • 是malloc的简单包装,特点是将动态分配的内存初始化为0.
2.4 alloca ():

说明:

  • 在栈中分配size个字节的内存空间,函数返回时自动释放掉该空间。
3 内存常用管理函数: 3.1 memcpy():
extern void* memcpy(void* des, const void* src,size_t n)
  • 从src copy n 个字节数据到des地址。
  • 类似strncpy()只是strncpy() 参数为char* 类型。
  • 类似bcopy(), 只是bcopy 多用于网络编程中。
3.2 memmove():
extern void* memmove(void* dest, void* src,size_t n)
  • 类似memcpy ,当dest 和src 没有重合时,与memcpy相同
  • 当dest与src 有重叠时,先处理再将src copy n 字节到dest.
3.3 memset():
extern void * memset(void *s, int _c, size_t _n)
  • 将s开始后面n位的值设置为c,执行成功返回s首地址。
  • 类似bzero()函数,bzero(s,n); 将s开始n字节设置为0
3.4 memchr()
extern void* memchr(const void* _s, int _c,size_t _n)
  • 在s中的前n个字节中查找c第一次出现的位置
3.5 memcmp():
extern int memcmp(const void* s1, void* s2, size_t _n)
  • 比较s1 和 s2 前n个字节是否相同
  • s1=s2 返回0, s1s2 返回1
  • 类似strncmp() 函数
文件与文件流及相关操作函数: 1.文件存储及操作分类:

文件存储分类:

  • 文本文件:ASCLL文件,文本文件存储量大,速度慢。文件以EOF结束
  • 二进制文件:存量小,速度快,便于存放中间结果

文件操作分类:

  • 缓冲文件操作:在用户空间自动为使用的文件开辟内存缓冲区,通过一次系统调用读取较多数据到缓冲区,这样避免每次读写都要进行系统调用。(系统调用会将CPU从用户态切换至内核态,影响效率)。
  • 非缓冲文件操作:最多只能在程序中开启缓存空间,每次读写都是一次系统调用。
2.标准流及流主要功能:
  • Linux 系统中,系统默认为每个进程打开3个文件,即每个进程默认可以操作3个流,标准输入流(/dev/stdin),标准输出流(/dev/stdout),标准错误输出流(/dev/stderr).
  • 每个进程从标准输入流读数据,向标准输出流写数据,向标准错误输出流写错误信息。
  • 可以通过重定向,修改输入流/输出流。
3.文件流指针:

在应用编程层面,程序对流的操作实际就是对文件流指针FILE的操作。操作一个文件前通过fopen()打开一个文件,返回该文件流指针且该指针与该文件关联。该文件流指针是一个文件描述符,对应的结构体可在用户空间进行访问。

4.缓冲区类型及指定: 4.1缓冲区分类:
  • 全缓冲区:该缓冲区默认大小与系统定义有关,大小定义在/usr/include/libio.h。 在缓冲区满或者调用刷新函数fflush() 后才进行I.O系统调用操作。普通磁盘文件的流通常使用全缓冲区访问。
  • 行缓冲区:行大小根据系统有关,通常默认128字节。当遇到换行符或缓冲区满时,行缓冲才刷新。终端使用行缓冲区古。
  • 不带缓冲区:标准I/O库不对字符进行缓存。标准出错流stderr 通常是不带缓冲区的,以便错误信息能够尽快显示出来。

使 用 缓 冲 区 , 不 需 要 每 次 进 行 标 准 I / O 处 理 时 都 使 用 系 统 I / O 调 用 color{red}{使用缓冲区,不需要每次进行标准I/O处理时都使用系统I/O调用} 使用缓冲区,不需要每次进行标准I/O处理时都使用系统I/O调用

4.2 缓冲区指定函数:

setbuf():

extern void setbuf(FILE* __stream,char* __buf);
  • 第一个参数为要操作的流对象
  • 第二个参数是指向BUFSIZ长度的缓冲区。如果buf设置为NULL,则关闭缓冲区。
  • 执行成功范围0,否则返回非0

setvbuf():

extern int servbuf(FILE* __stream, char* __buf, int __modes, size_t __n);
  • 第一个参数为要操作的流对象
  • 第二个参数buf指向一个长度为n大小的缓冲区
  • 第三个参数为缓冲区类型 ;#define _IOFBF 0 全缓冲;#define _IOLBF 1 行缓冲;#define _IonBF 2 无缓冲。
  • 如果指定不带缓冲区的流,则buf和n参数都忽略;如果buf=NULL,则系统默认分配适当大小的缓存区。
5 ANSI C文件I/O操作: 5.1 fopen()打开文件:
extern FILE* fopen(__const char* __filename,__const char* __modes);
  • 第一个参数为打开文件的绝对路径或者相对路径。
  • 第二个参数为打开方式:具体如下:
  • 函数执行成功则返回文件指针,如果文件打开失败则返回NULL
5.2 关闭文件fclose() /fcloseall():

fclose():

extern int fclose(FILE* __stream)
  • 参数为文件流指针
  • 当close文件时, 操 作 系 统 会 自 动 将 缓 冲 区 的 内 容 回 写 到 文 件 color{red}{操作系统会自动将缓冲区的内容回写到文件} 操作系统会自动将缓冲区的内容回写到文件
  • 成功返回0,否则返回EOF, 并设置errno 全局变量。
extern int fcloseall(void);
  • 关闭所有流对象。如进程关闭时,需要关闭打开的所有流对象。
5.3 更新缓冲区内容fflush:

通过I/O系统调用将缓冲区内容写会磁盘中。

extern int fflush(FILE* __stream);
  • 函数执行成功返回0,否则返回EOF,并设置标准错误error
5.4 字符读操作:
extern int fgetc(FILE * __stream); //从流中读一个字符
extern int getc(FILE *__stream);   //#define getc(_fp) _IO_getc(_fp)
  • 每次系统调用只从流中读出一个字符。
  • 成功返回读的内容,失败或文件结束则返回EOF(-1)
  • feof() 检测是否督导结束
  • ferror() 检测是否出错
  • 比如fgetc(stdin) 从标准输入流读一个字符。标准输入读一个字符还可以使用getchar() //extern int getchar(void);
5.5 字符写操作,标准流中写一个字符:
extern int fputc(int __c, FILE* __stream)  //将字符c写到流stream中
extern int putc(int __c, FILE* __stream)
  • 向标准输出流写一个字符可用putchar()相当于fputc(c,stdout). //extern int putchar(int __c);
  • 调用成功返回内容,失败返回-1
5.6 行读出操作:
extern char* fgets(char* __s, int __n, FILE *__stream)
  • 从strean 中读取n-1个字符存放到s中。
  • 成功返回s,失败(到文件尾部或出错)则返回NULL,
5.7 行写入操作:
extern int fputs(__const char* __s, FILE* __stream)
extern int puts(__const char* __s)  //输出流到标准输出设备中
  • fputs 将s指向的以空字符结尾的字符串写入stream中
  • puts()将s指向的以空字符结尾的字符串写入标准输出
  • 成功返回非负,失败返回-1
5.8 块读出操作:
extern size_t fread(void* __ptr,size_t __size, size_t __n, FILE* __stream)
  • 从stream 中读取n个大小为size的对象,存放在ptr所指的内存空间。
  • 返回实际读取到对象的个数,如果返回值
5.9 块写入操作:
extern size_t fwrite(__const void* __ptr, size_t __size, size_t __n, FILE *__S);
  • 从ptr 中读取n个大小为size的对象写入s指向的stream中。
  • 执行成功,函数返回实际写入的对象个数。
5.10 feof() 文件末尾检测函数:
extern int feof(FILE* __stream)
  • ASCLL文件可以直接根据返回值是否=EOF判断
  • 二进制文件需要使用该函数,返回1表示读到文件结束,否则返回0
5.11 ferror() 函数判断给定流是否错误:
extern int ferror(FILE* stream)
  • 没有错误将返回0
  • 否则返回错误符
5.12 clearerr() 清除错误标识位
extern void clearerr(FILE* __stream)
  • feof 或ferror 执行后,如果出现错误,将设置错误标识符,执行错误处理后需要清除错误标识符。
5.13 ftell() 返回当前读写位置:
extern long int ftell(FILE* __stream)
  • 成功返回流的当前读写位置距离文件开始的字节数
  • 失败返回-1
5.14 fseek() 修改当前读写位置。
extern int fseek(FILE* __stream, long int __off, int__whence)
  • 第一个参数为stream 流
  • 第二个参数为基于修改基础的偏移量
  • 第三个参数为修改位置的基准;SEEK_SET :文件开始;SEEK_CUR:当前位置;SEEK_END:文件结束位置
5.15 rewind() 重置当前读写位置
extern void rewind(FILE * __stream)

将读写指针移动到文件开头

案例:

FILE* fp_src;
fp_src=fopen("/mytest.cpp",r+);
if(fp_src==NULL)
	perror("errorn");

do{
	num=fread(buf, 1, 128, fp_src);  //读取128字节到buf中
	if(feof(fp_src)==1)
	break;
}while(1)

fclose(fp_src);
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/618629.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号