码迷,mamicode.com
首页 > 编程语言 > 详细

C语言小知识收集

时间:2015-08-19 21:25:47      阅读:144      评论:0      收藏:0      [点我收藏+]

标签:

#define min(x,y) ({ \
    typeof(x) _x = (x);    \
    typeof(y) _y = (y);    \

    (void) (&_x == &_y);    \ // 为了当x,y 是表达式的时候,编译报错如i++,j++; 或者是 x y 不是同一个类型                                        的时候,不同的指针比较编译警告。

_x < _y ? _x : _y; })

// android binder

struct binder_buffer {
    struct list_head entry; /* free and allocated entries by address */
    struct rb_node rb_node; /* free entry by size or allocated entry */
                /* by address */
    unsigned free:1;
    unsigned allow_user_free:1;
    unsigned async_transaction:1;
    unsigned debug_id:29;

    struct binder_transaction *transaction;
#ifdef BINDER_MONITOR
    struct binder_transaction_log_entry *log_entry;
#endif
    struct binder_node *target_node;
    size_t data_size;
    size_t offsets_size;
    uint8_t data[0]; // 获得一个内存地址标记并可以节省不必要的存储空间
};

        buffer = rb_entry(n, struct binder_buffer, rb_node);
        tmp_size = binder_buffer_size(target_proc, buffer);// 计算 buffer 的容量大小。由于内存是线性增长分配的,并且在entry 中按地址排列,所以 由 下一个buffer 的地址- 这个buffer的data 就是 当前buffer大小。

static size_t binder_buffer_size(struct binder_proc *proc,
                 struct binder_buffer *buffer)
{
    if (list_is_last(&buffer->entry, &proc->buffers))
        //proc->buffer_size =   vma->vm_end - vma->vm_start

        return proc->buffer + proc->buffer_size - (void *)buffer->data;

    else
        return (size_t)list_entry(buffer->entry.next,
            struct binder_buffer, entry) - (size_t)buffer->data;

}


// 位域,不是所有的编译器都支持这种用法,对于有些编译器一个位域不能跨字节,不够的话,从下个字节开始。

      struct   _a  
   
            {  
   
              int   a:1  
   
              int     :2                     /*该2位不能使用*/  
   
              int   b:3  
   
              int   c:2  
   
            }; 

  struct   _b
   
            {  
   
                unsigned   a:4  
   
                unsigned   :0                 /*空域*/  
   
                unsigned   b:4               /*从下一单元开始存放*/  
   
                unsigned   c:4  
   
            }  


// 红黑树的实现,红黑树通过着色保持到NULL 节点最长的路径最多是最短的路径两倍。以达到普通二叉树与平衡二叉树的折中选择。

着色只有红黑两种,可以用一位,来表示;tree_node 的三要素 parent ,child_left, child_right ,可以肯定

每个节点都有唯一的parent;看下面的 struct rb_node 是 (aligned(sizeof(long))) 对齐的;这样指向 parent node 的地址parent 两位最低权值的bit 位为00是确定的,没有有效的信息熵,可以用来承载rb_node 的color 信息。所以__rb_parent_color才会有下面 rb_parent 宏 ,以及rb_set_parent ,rb_set_parent_color 函数。


struct rb_node {
    unsigned long  __rb_parent_color;
    struct rb_node *rb_right;
    struct rb_node *rb_left;
} __attribute__((aligned(sizeof(long))));

#define rb_parent(r)   ((struct rb_node *)((r)->__rb_parent_color & ~3)

struct rb_root {
    struct rb_node *rb_node;
};

static inline void rb_set_parent(struct rb_node *rb, struct rb_node *p)
{
    rb->__rb_parent_color = rb_color(rb) | (unsigned long)p;
}

static inline void rb_set_parent_color(struct rb_node *rb,
                       struct rb_node *p, int color)
{
    rb->__rb_parent_color = (unsigned long)p | color;
}



C语言小知识收集

标签:

原文地址:http://my.oschina.net/u/269082/blog/494731

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!