结构体中的冒号位域

有些信息在存储时,并不需要占用一个完整的字节, 而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1 两种状态, 用一位二进位即可。为了节省存储空间,并使处理简便,C语言又提供了一种数据结构,称为“位域”或“位段”。所谓“位域”是把一个字节中的二进位划分为几个不同的区域,并说明每个区域的位数。每个域有一个域名,允许在程序中按域名进行操作。这样就可以把几个不同的对象用一个字节的二进制位域来表示。一、位域的定义和位域变量的说明位域定义与结构定义相仿,其形式为:

域结构名

{ 位域列表 };

其中位域列表的形式为: 类型说明符 位域名:位域长度 例如:

struct bs 
{ 
    int a:8; 
    int b:2; 
    int c:6; 
};

位域变量的说明与结构变量说明的方式相同。 可采用先定义后说明,同时定义说明或者直接说明这三种方式。例如:

struct bs 
{ 
    int a:8; 
    int b:2; 
    int c:6; 
}data;

说明data为bs变量,共占两个字节。其中位域a占8位,位域b占2位,位域c占6位。对于位域的定义尚有以下几点说明: \1. 一个位域必须存储在同一个字节中,不能跨两个字节。如一个字节所剩空间不够存放另一位域时,应从下一单元起存放该位域。也可以有意使某位域从下一单元开始。例如:

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

这个位域定义中,a占第一字节的4位,后4位填0表示不使用,b从第二字节开始,占用4位,c占用4位。 \2. 位域可以无位域名,这时它只用来作填充或调整位置。无名的位域是不能使用的。例如:

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

从以上分析可以看出,位域在本质上就是一种结构类型, 不过其成员是按二进位分配的。 简而言之,言而简之 这是位域操作的表示方法,也就是说后面加上“:1”的意思是这个成员的大小占所定义类型的1 bit,“:2”占2 bit,依次类推。当然大小不能超过所定义类型包含的总bit数。 一个bytes(字节)是8 bit(bit)。例如你的结构中定义的类型是u_char,一个字节,共8bit,最大就不能超过8。 32位机下, short是2字节,共16bit,最大就不能超过16. int是4字节,共32bit,最大就不能超过32. 依次类推。 这样定义比较省空间。例如你上面的结构,定义的变量类型是u_char,是一字节类型,即8bit。 fc_subtype占了4bit,fc_type占2bit,fc_protocol_version占2bit,共8bit,正好是一个字节。 其他八个成员,各占1bit,共8bit,正好也是一个字节。 因此你的结构的大小如果用sizeof(struct frame_control)计算,就是2bytes.

埃拉托斯特尼筛选法

埃拉托斯特尼筛选法又称筛法,是求不超过自然数N(N>1)的所有质数的一种方法。据说是古希腊的埃拉托斯特尼(Eratosthenes,约公元前274~194年)发明的,又称埃拉托斯特尼筛子。 具体做法是: 先把N个自然数按次序排列起来。1不是质数,也不是合数,要划去。第二个数2是质数留下来,而把2后面所有能被2整除的数都划去。2后面第一个没划去的数是3,把3留下,再把3后面所有能被3整除的数都划去。3后面第一个没划去的数是5,把5留下,再把5后面所有能被5整除的数都划去。这样一直做下去,就会把不超过N的全部合数都筛掉,留下的就是不超过N的全部质数。因为希腊人是把数写在涂腊的板上,每要划去一个数,就在上面记以小点,寻求质数的工作完毕后,这许多小点就像一个筛子,所以就把埃拉托斯特尼的方法叫做“埃拉托斯特尼筛”,简称“筛法”。(另一种解释是当时的数写在纸草上,每要划去一个数,就把这个数挖去,寻求质数的工作完毕后,这许多小洞就像一个筛子。)

    using std::size_t;
    using std::sqrt;
    using std::string;

    class SieveTest : public TestSuit::Test {
        string sieveChars;
    public:
        SieveTest() : sieveChars(50, 'P') {}
        void run() {
            findPrimes();
            testPrimes();
        }   
        bool isPrime(int p) {
            if(p == 0 || p == 1) return false;
            int root = int(sqrt(double(p)));
            for(int i = 2; i <= root; i++)
                if(p % i == 0) return false;
            return true;
        }   
        void findPrimes() {
            sieveChars.replace(0, 2, "NN");
            size_t sieveSize = sieveChars.size();
            int root = int(sqrt((double)(sieveSize)));
            for(int i = 2; i <= root; i++)
                for(size_t factor = 2; factor * i < sieveSize; ++factor)
}
        void testPrimes() {
            size_t i = sieveChars.find('P');
            while(i != string::npos) {
                test_(isPrime(i++));
                i = sieveChars.find('P', i);
            }
            i = sieveChars.find_first_not_of('P');
            while(i != string::npos) {
                test_(!isPrime(i++));
                i = sieveChars.find_first_not_of('P', i);
            }
        }
    };

ref: http://zh.wikipedia.org/wiki/%E5%9F%83%E6%8B%89%E6%89%98%E6%96%AF%E7%89%B9%E5

xlib创建一个OpenGL简单窗口

void CreateWindow(int width, int height) {
	XInitThreads();
	m_scrWidth = width;
	m_scrHeight = height;
	int attr[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DOUBLEBUFFER, True,
			GLX_DEPTH_SIZE, 16, None, };
	m_dpy = XOpenDisplay(NULL);
	if (m_dpy == NULL) {
		cerr << "XOpenDisplay error" << endl;
		return;
	}
	int nelements;
	GLXFBConfig *fc = glXChooseFBConfig(m_dpy, 0, attr, &nelements);
	if (fc == NULL) {
		cerr << "glXChooseFBConfig error" << endl;
		return;
	}
	XVisualInfo *vi = glXGetVisualFromFBConfig(m_dpy, *fc);
	if (vi == NULL) {
		cerr << "glXGetVisualFromFBConfig error" << endl;
		return;
	}
	Colormap cmap = XCreateColormap(m_dpy, DefaultRootWindow(m_dpy), vi->visual,
			AllocNone);
	XSetWindowAttributes swa;
	swa.colormap = cmap;
	swa.event_mask = ExposureMask | KeyPressMask;
	m_win = XCreateWindow(m_dpy, DefaultRootWindow(m_dpy), 0, 0, m_scrWidth,
			m_scrHeight, 0, vi->depth, InputOutput, vi->visual,
			CWColormap | CWEventMask, &swa);
	XFree(vi);
	/* 显示窗口 */
	XMapWindow(m_dpy, m_win);
	/* 设置窗口的OpenGl属性 */
	m_glc = glXCreateNewContext(m_dpy, *fc, GLX_RGBA_TYPE, NULL, GL_TRUE);
	/* 绑定当前窗口到OpenGl */
	glXMakeContextCurrent(m_dpy, m_win, m_win, m_glc);
	/* 初始化OpenGl */
	initializeGl();
	glXSwapBuffers(m_dpy, m_win);
}

Valgrind学习笔记

valgrind --tool=memcheck --leak-check=yes ls -l
valgrind --leak-check=full  --track-origins=yes  --track-origins=yes  --leak-check=full --show-reachable=yes -v 
valgrind  --tool=exp-dhat  --tool=massif --tool=callgrind --tool=memcheck --leak-check=full  --track-origins=yes  --track-origins=yes  --leak-check=full --show-reachable=yes -v 

Linux查看系统使用的线程库

getconf GNU_LIBPTHREAD+VERSION