分类 编程.C 中的文章

八个基础排序

sort排序

std::sort( )函数是库函数提供的排序函数,必须包括头文件#include <algorithm>,它使用的排序方法是类似于快排的方法,时间复杂度为n*log2(n)

Sort函数有三个参数:(第三个参数可不写)

……

阅读全文

实现atoi和itoa函数

题目1: 把字符串转化为整数

有整数字符串,"13579", 和 "246810". 请写一个函数把这两个字符串转化为整数
步骤:

  • 先判断正负
  • 遍历字符串,转换字符为整数
//atoi.cc
#include  <stdio.h>
int my_atoi(char *str)
{
    bool bmin = false;
    int result = 0;
    //先判断正负
    if ((*str > '9' || *str < '0') && (*str == '+' || *str == '-'))
    {
        if (*str == '-') bmin = true;
        str++;
    }
    
    while (*str != '\0')
    {
        if (*str > '9' || *str < '0') break;

        //printf("befter str: %s\n", str);
        result = result * 10 + (*str++ - '0');
        //printf("after str: %s\n", str);
    }
    if (*str != '\0')    return 0;

    return bmin ? -result : result;
    
}


int main()
{
    char a[] = "13579";
    char b[] = "246810";

    printf("a: %d\n", my_atoi(a));
    printf("b: %d\n", my_atoi(b));
}

编译&运行

……

阅读全文

协程解析二 | 云风的coroutine

概述

云风的coroutine是通过ucontext来控制程序运行时上下文的,我们来根据该库提供的几个接口,和一个demo来解释协程的运行原理。如果不了解ucontext的,建议先了解ucontxt

环境

下载代码 & 编译

……

阅读全文

协程解析一 | ucontext

概述

最近在研究协程的实现原理,看了云风的coroutine和腾讯的开源库libco后,原来要实现一个协程库也没那么难。我先来讲讲云风的coroutine库。他使用的是 uncontext来保存程序运行上下文,进而实现协程库,这个库很值深入了解一番,吃透了这个库,协程的原理也就了解了。

……

阅读全文

struct中使用char[]

缘由

最近在看redis的源码,刚开始看sds,看到这块代码

struct __attribute__ ((__packed__)) sdshdr5 {
    unsigned char flags; /* 3 lsb of type, and 5 msb of string length */
    char buf[];
};

好奇为什么使用 char buf[],而不用char *buf,找到答案记录一下。

struct中的char*和char数组有什么区别

常用来构成缓冲区。比起指针,用空数组有这样的优势:

……

阅读全文

CCnet | 单线程reactor演变为多线程

ccnet从单线程演变为多线程

ccnet现状:

  • epoll
  • linux平台
  • 事件循环
  • 单线程
  • reactor
  • 监听和新连接的事件都在主线程中

单线程的ccnet

98fb4a422ca29f30211176d1b81489fd.png
ccnet的单线程的角色:

  • EventLoop: 整个事件循环。
  • EPollPoller: 负责事件的收集。
  • Channel:负责事件的分发。
  • Acceptor:处理客户端新连接,绑定监听回调时间。
  • TcpConnection: 包含EventLoop组件,Channel组件,接收缓冲区和发送缓冲区,负责数据的收发。
  • TcpServer:包含EventLoop组件,Acceptor组件,客户端连接map,还有回调接口
  • Buffer: 缓冲区

*ccnet的单线程模型只是对epoll进行了封装,然后根据reactor模型在代码上进行了组件的区分,但是整体操作还是单线程,不能充分利用硬件资源。TcpServer的回调函数中,数据接收和业务处理在同一条线程中。

……

阅读全文

CCnet | 一个reactor单线程网络库

缘由

最近在研究陈硕的网络库muduo,是一个基于reactor架构的网络库。我对网络库的感觉是易用,但是内容庞大,依赖颇多。比如boost网络库里面的一些语法让人生畏。关于reactor和proactor架构,还有select/poll/epoll网络模型方面的基础理论知识已经掌握,自己也一直想做一个网络库来对自己之前工作的一个总结。muduo整体代码量不多,易读,整个架构也容易理解,于是我模仿muduo写了一个单线程的reactor网络库。

……

阅读全文

C++ | vector中的resize()函数 VS reserve()函数

reserve

void reserve (size_type n);

reserver函数用来给vector预分配存储区大小,即capacity的值 ,但是没有给这段内存进行初始化。reserve 的参数n是推荐预分配内存的大小,实际分配的可能等于或大于这个值,即n大于capacity的值,就会reallocate内存 capacity的值会大于或者等于n 。这样,当ector调用push_back函数使得size 超过原来的默认分配的capacity值时 避免了内存重分配开销。

……

阅读全文

Libevent | 定时器

libevent 实现定时器流程

首先初始化libevent库,并保存返回的指针

struct event_base * base = event_init();  

实际上这一步相当于初始化一个Reactor实例;在初始化libevent后,就可以注册事件了。

初始化事件event,设置回调函数和关注的事件 ,事实上这等价于调用event_set(&ev, -1, 0, timer_cb, NULL);

……

阅读全文