![](https://img-blog.csdnimg.cn/20201014180756925.png?x-oss-process=image/resize,m_fixed,h_64,w_64)
C语言
文章平均质量分 78
_200_
这个作者很懒,什么都没留下…
展开
-
C++函数重载
C++函数重载函数重载,就是可以定义多个参数列表不同函数名相同的函数,编译的时候不好产生错误。C++支持函数重载,但在C中是不支持的,编译无法通过。查看C和C++编译时生成的函数符号表:可以看到,gcc编译时符号表生成的函数符号只有函数名,而g++编译除了函数名外,参数列表也会参与函数符号命名。在gcc中编写同名函数会出现链接错误,因为他们生成的函数符号都是一样的,链接器不知道要链接哪个符号。#include <iostream>#include <string.h>原创 2022-04-26 11:09:23 · 149 阅读 · 0 评论 -
const和指针的结合
const和指针的结合在定义一个const指针常量的时候,不同位置的const产生的结果也是不同的。首先我们需要知道,一个普通的指针是不能指向一个常量的地址的:#include <stdio.h>int main(){ const int a = 10; int* p = &a;}上面的代码编译时无法通过的,这是因为a是一个常量,而如果我们把a的地址泄露给了一个普通的指针p,就相当于我们可以通过*p来间接修改a内存的值,这就有违背使用常量的初衷。但我们用一个常指针原创 2022-04-24 23:07:40 · 492 阅读 · 0 评论 -
C和C++中const的区别
C和C++中const的区别众所周知,C和C++中用const修饰的变量初始化完成后,值不能被修改,不能再作为左值。#include <stdio.h>int main(){ const int a = 10; a = 20;}不管是在C还是C++中,上面的代码都是不能被编译通过的。而在C和C++中,const的使用还是有很多不同的。初始化在C++中,const修饰的变量必须要初始化,否则编译不通过;而在C中,const修饰的变量是可以不用初始化的,但如果const修饰的原创 2022-04-24 21:14:16 · 979 阅读 · 0 评论 -
I/O复用 epoll系统调用
I/O复用 epoll系统调用epoll内核事件表epoll_wait函数LT和ET模式epoll内核实现代码示例epoll内核事件表epoll是Linux特有的I/O复用函数。它在实现和使用上与select、poll 有很大差异。首先,epoll 使用一组函数来完成任务,而不是单个函数。其次,epoll 把用户关心的文件描述符上的事件放在内核里的一个事件表中,从而无须像select和poll那样每次调用都要重复传人文件描述符集或事件集。但epoll需要使用一个额外的文件描述符, 来唯一标识内核中的这个原创 2022-02-11 12:47:16 · 739 阅读 · 0 评论 -
I/O复用 poll系统调用
I/O复用 poll系统调用poll APIpoll系统调用的用途是:在一段指定时间内,轮询一定数量的文件描述符,以测试其中是否有就绪者。poll APIpoll的原型如下:#include <poll.h>int poll(struct pollfd *fds, nfds_t nfds, int timeout);poll 系统调用成功返回就绪文件描述符的总数,超时返回 0,失败返回-1。nfds 参数指定被监听事件集合 fds 的大小。timeout 参数指定 poll 的原创 2022-02-11 10:55:39 · 595 阅读 · 0 评论 -
I/O复用 select系统调用
I/O复用 select系统调用select APIselect 原理分析select的代码示例select 系统调用的用途是:在一段指定时间内,监听用户感兴趣的文件描述符的可读、可写和异常等事件。select APIselect 系统调用的定义如下:#include <sys/select.h>int select(int maxfd, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *ti原创 2022-02-10 21:39:25 · 676 阅读 · 0 评论 -
dup函数和dup2函数
dup函数和dup2函数有时我们希望把标准输入重定向到一个文件,或者把标准输出重定向到一个网络连接。这可以通过我们要介绍的用于复制文件描述符的dup和dup2函数来实现:#include <unistd.h>int dup( int filedescriptor );int dup2( int file_descriptor_one, int file_descriptor_two);dup函数创建一个新的文件描述符,该新文件描述符和原有文件描述符file_descriptor 指向原创 2022-02-05 11:04:23 · 890 阅读 · 0 评论 -
Linux进程间通信之消息队列
Linux进程间通信之消息队列消息队列的介绍消息队列函数msgget函数msgsnd函数msgrcv函数msgctl函数编程实例msg1.cmsg2.c程序分析消息队列的介绍消息队列与有名管道有许多相似之处,但少了在打开和关闭管道方面的复杂性。但使用消息队列并未解决我们在使用命名管道时遇到的一些问题, 比如管道满时的阻塞问题。消息队列提供了一种在两个不相关的进程之间传递数据的相当简单且有效的方法。与命名管道相比,消息队列的优势在于,它独立于发送和接收进程而存在,这消除了在同步命名管道的打开和关闭时可能原创 2022-01-15 20:07:07 · 218 阅读 · 0 评论 -
Linux进程间通信之信号
Linux进程间通信之信号信号的基本概念信号处理函数signal发送信号函数kill和alarm信号的基本概念信号是UNIX和Linux系统响应某些条件而产生的一个事件。 接收到该信号的进程会相应地采取一些行动。我们用术语生成(raise) 表示一个信号的产生,使用术语捕获(catch) 表示接收到一个信号。信号是由于某些错误条件而生成的,如内存段冲突、浮点处理器错误或非法指令等。它们由shelI和终端处理器生成来引起中断,它们还可以作为在进程间传递消息或修改行为的一种方式, 明确地由一个进程发送给另原创 2022-01-15 11:22:35 · 689 阅读 · 0 评论 -
Linux进程间通信之共享内存
Linux进程间通信之共享内存shmget函数shmat函数shmdt函数shmctl函数共享内存允许两个不相关的进程访问同一块逻辑内存,是在两个正在运行的进程之间传递数据的一种非常有效的方式。大多数共享内存的具体实现,都把由不同进程之间共享的内存安排为同一段物理内存。共享内存是由IPC为进程创建的一个特殊的地址范围,它将出现在该进程的地址空间中。其他进程可以将同一段共享内存连接到它们自己的地址空间中。所有进程都可以访问共享内存中的地址,就好像它们是由malloc分配的一样。 如果某个进程向共享内存写入原创 2022-01-13 19:15:30 · 700 阅读 · 0 评论 -
Linux进程间通信之信号量
Linux进程间通信之信号量当我们编写的程序使用了线程时,不管它是运行在多用户、多进程、多用户多进程系统上,我们通常会发现,程序中有一部分临界代码,我们需要确保只有一个进程(或线程)可以进入这个邻居代码并拥有对资源独占式的访问权。要想编写通用的代码,以确保程序对某个特定的资源具有独占式的访问权是非常困难的。虽然有一个名为Dekker算法的解决方法,但这个算法依赖于“忙等待”或“自旋锁”。也就是说,一个进程要持续不断地运行以等待某个内存位置被改变。在像Linux这样的多任务环境中,人们并不愿意使用这种原创 2022-01-12 21:54:04 · 754 阅读 · 0 评论 -
Linux进程间通信之有名管道编程
Linux进程间通信之有名管道编程有名管道的创建访问FIFO文件命令行访问程序中访问FIFO文件使用open打开FIFO文件无名管道虽然可以在两个进程间交换数据,但也仅限于在相关的程序之间传递数据,即这些程序是由一个共同的祖先进程启动的。但如果我们想在不相关的进程间交换数据,这还是很不方便。我们可以用有名管道来完成这项工作。有名管道(FIFO)是一种特殊类型的文件,它在文件系统中以文件名的形式存在,但它的行为却和无名管道类似。有名管道的创建我们可以在命令行上创建命名管道,也可以在程序中创建它。命令行原创 2022-01-11 13:20:17 · 565 阅读 · 0 评论 -
Linux进程间通信之管道编程实例
Linux进程间通信之管道编程实例popen函数和pclose函数popen函数pclose函数实例1:读取外部程序的输出实例2:将输出送往popenpopen函数的优缺点pipe调用fork不exec时的pipe调用fork+exec时的pipe调用当从一个进程连接数据到另一个进程时,我们通常是把一个进程的输出通过管道连接到另一个进程的输入。Linux环境下可以把shell命令连接在一起,就是把一个进程的输出直接传递给另一个进程的输入。对于shell命令来说,命令的连接是通过管道字符来完成的,如下所示原创 2022-01-10 11:20:25 · 951 阅读 · 0 评论 -
链表中环的入口结点
链表中环的入口结点题目:如果一个链表中包含环,如何找出环的入口点?例如:下图所示的链表,环的入口结点是结点3解决这个问题的第一步是如何确定一个链表中包含环。一个包含环的链表,一直向前遍历是无穷次的。那么我们可以用两个快慢指针来解决这个问题。定义两个指针,一个一次走一步,另一个一次走两步。如果快指针追上了慢指针,那么表示链表有环。如果快指针到达链表尾部(next域为空),说明链表无环。确定链表有环之后,我们接下来就是找环的入口了。我们可以用两个指针来解决这个问题。先定义两个指针p1和p2指向原创 2022-01-07 15:42:25 · 304 阅读 · 0 评论 -
头指针单链表的C语言代码实现
头指针单链表的实现point_list.hpoint_list.ctest_main.cpoint_list.h测试代码仅测试插入,删除请自行测试typedef int ElemType; typedef struct Node { ElemType data; struct Node *next; }PointList;void InitPointList(PointList** pp); // 初始化 bool InsertPointList(PointList **pp, El原创 2022-01-05 14:32:26 · 510 阅读 · 0 评论 -
带头结点单链表的C语言代码实现
带头结点单链表的实现head_list.hhead_list.ctest_main.c测试代码仅测试插入,删除请自行测试head_list.htypedef int ElemType;typedef struct Node { ElemType data; struct Node *next;}HeadList;void InitHeadList(HeadList* head);int GetLength(HeadList* head);void ShowList(HeadLis原创 2022-01-05 00:15:00 · 376 阅读 · 0 评论 -
单链表中倒数第K个结点
单链表中倒数第K个结点链表结点定义如下:typedef int ElemType;typedef struct Node { ElemType data; struct Node *next;}HeadList;为了得到倒数第k个结点,很自然的想法是先走到链表的尾部,再从尾部回溯k步。而题中所给的链表结点定义可以看出是单向链表,没有从后往前的指针,因此这种思路是行不通的。既然不能从尾部回溯,我们可以把思路回到头结点上。假设整个链表有n个结点,那么倒数第k个结点就是从头结点开始的第n原创 2022-01-07 13:55:27 · 1228 阅读 · 1 评论 -
O(1)时间下删除链表的结点
O(1)时间下删除链表的结点在给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间内删除该结点。链表的结点结构如下:typedef int ElemType; typedef struct Node { ElemType data; struct Node *next; }PointList;在单链表中删除一个结点,常规的做法无疑是从链表的头节点开始,顺序遍历查找要删除的结点,并在链表中删除该结点。如上图所示的链表中,我们想删除结点i,可以从链表的头结点开始顺序遍历,发现h的原创 2022-01-06 22:27:06 · 148 阅读 · 0 评论 -
静态链表的C语言代码实现
静态链表的C语言代码实现static_link_list.hstatic_link_list.ctest_main.c以下代码仅测试插入操作,删除操作请自行测试static_link_list.h#define MAXSIZE 1000typedef int ElemType;typedef struct { ElemType data; int cur;}Component, StaticLinkList[MAXSIZE];bool InitList(StaticLinkList原创 2022-01-06 19:37:28 · 316 阅读 · 0 评论 -
C语言预处理
C语言预处理#include预处理命令#define预处理命令:符号常量#define预处理命令:宏带参数的宏#undef预处理命令条件编译#if... #endif预处理命令#error和#pragma预处理命令#和# #运算符断言和符号常量NDEBUGC的预处理实在程序被编译之前执行的。执行的处理操作有:将其他文件包含到正在被编译的文件中来定义符号常量和宏程序代码的条件编译有条件地执行预处理命令所有的预处理命令都是以#开头的。在同一行中,只有空格和注释可以出现在预处理命令之前。#i原创 2022-01-04 18:08:18 · 343 阅读 · 0 评论 -
C语言Linux环境下使用命令行实参
C语言Linux环境下使用命令行实参Linux环境下,通过将形参int argc和char *argv[]包含在main函数的形参列表中,就可以从命令行像main函数传递实参。形参argc接收的是用户输入的命令行中实参的个数,形参argv是一个用来存储实际的命令行实参的字符串数组。命令行实参的一般用途是向程序传递一些选项或者文件名。...原创 2022-01-03 22:09:04 · 448 阅读 · 0 评论 -
C语言可变长的参数列表
C语言可变长的参数列表C语言可创建接收参数个数不确定的函数。如常用的标准库函数printf就是一个接收参数个数可变的函数。函数printf至少要接收一个字符串作为它的第一个实参。但事实上,printf还能够接收任意数目的其他实参。printf的函数原型是:int printf(const char *format, ...);其中的省略号(…)表示这个函数可以接收可变数目的各种类型的实参。需要注意:这个省略号必须放在形参列表的末尾。可变参数头文件<stdarg.h>中的宏和定义,为创建原创 2022-01-03 21:08:21 · 326 阅读 · 1 评论 -
C语言文件处理
C语言文件处理文件与流文件与流将数据存储在变量或数组中,数据在程序运行结束后这些数据将会被释放,而文件则可以永久地保存数据。C语言中,文件不过是一个按顺序组成地字节流。原创 2022-01-03 19:31:48 · 1030 阅读 · 0 评论 -
结构体位域
结构体、共同用体位域位域的定义无名位域当结构体或共用体中包含无符号整型或有符号整型成员时,C语言允许用户指定这些成员所占用的存储位数。这被称为位域。通过将数据存储在它们所需的最小数目的存储位内,位域能够有效的提高存储空间的利用率,有助于减少程序所需的存储空间。位域成员必须被声明为有符号整型或无符号整型。位域没有地址,&(取地址运算符)不能运用于位域。位域的定义struct bitCard { unsigned int face : 4; unsigned int suit : 2;原创 2022-01-03 14:48:28 · 289 阅读 · 0 评论 -
结构体sizeof运算、字节对齐
sizeof求结构体、共用体字节数用sizeof求结构体变量所占的字节数。用sizeof求结构体变量所占的字节数。用sizeof求结构体变量所占的字节数,并不是简单的把各个成员的字节数相加。在计算机存储系统中以字节为单位存储数据,不同的数据类型所占的空间不同,例如:整型数据(int)占4个字节、字符型数据(char)占1个字节、浮点型数据(float)占四个字节…计算机为了快速的读写数据,默认情况下将数据存放在某个地址的起始位置,例如:整形数据(int)默认存储在地址能被4整除的起始位置、字符型数据原创 2022-01-03 13:19:46 · 470 阅读 · 0 评论 -
C语言结构体
C语言结构体结构体的定义自引用结构体定义结构体类型的变量对结构体的合法操作结构体是统一在同一个名字之下的一组相关变量的集合。结构体可以包含不同数据类型的变量——与只包含相同数据类型元素的数组相反。将结构体和指针联合使用,可以实现更复杂的数据结构,如链表、队列、堆栈和树。结构体的定义结构体属于派生数据类型,即它们是用其他数据类型的对象来构建的。看下这个结构体的定义:struct card{ char *face; char *suit;};定义一个结构体的关键字是struct,标识符ca原创 2022-01-02 15:36:55 · 667 阅读 · 0 评论 -
C语言格式化输出
C语言格式化输入/输出1、流任何问题的求解都有一个重要的组成部分,那就是显示结果。下面,将深入谈论函数sacnf和printf的格式化输入/输出功能。这两个函数从标准输入流(Standard input stream)输入数据,并将数据输出道标准输出流(Standard output stream)。在调用这些函数的程序中应包含头文件<stdio.h>.1、流所有的输入/输出都是基于流(Stream)实现的,所谓流就是字节的序列。在输入操作中,字节从一个外部设备(如键盘、硬盘、网卡)流向主原创 2021-12-29 18:24:36 · 6081 阅读 · 0 评论