
C/C++
文章平均质量分 72
jcwKyl
吾尝终日而思矣,不如须臾之所学也。
展开
-
打印数据在内存中的二进制存储格式
本来是在>第一卷看到的一个代码。当时对自己触动非常大。今天在论坛看到有人问类似的东西,就按那个想法自己用c语言写了一个,算是做个小小的纪念:#include stdio.h>void printBinary(unsigned char* mem, int size) ...{ int i; while(size--) ...{ printf("%p: ", mem原创 2008-04-08 12:56:00 · 2435 阅读 · 2 评论 -
复杂的指针声明的两种解读方法
例如下面两个声明:char* const*(*ss[23][200])(void (*)(int h, void (*)(void))));int *(*f4())[10]();上面两个例子都是从经典的C/C++书上找到的。《C++编程思想》和《C FAQS》两本书上总共给出了两种解读的方法:使用cdecl工具;从标识符开始按照右——左——右——……这个顺序手工解读。第一种原创 2009-04-18 12:28:00 · 1474 阅读 · 0 评论 -
GNU C对ISO标准的扩展——笔记(一)
在朋友的博客上看到这样的C语言初始化方式:int arr[10] = { [5] = 7 }; // a[5] = 7;以前没有用过也不知道有这样的写法。在网上找了一下这方面的资料,最后在http://gcc.gnu.org/onlinedocs/gcc-3.2.3/gcc/C-Extensions.html找到了答案。以下所有内容都来自这个网址。上面的那行C语言初始化语法叫做Designat原创 2009-04-20 22:58:00 · 3596 阅读 · 0 评论 -
当bsearch要查找的key是字符数组
这两天写C程序遇到这个问题。总结起来,如果使用qsort对字符串数组(char* arr[]类型的数组)排序,或者使用bsearch查找的key是一个字符数组,则有两点需要注意:一:qsort和bsearch使用的比较函数的参数都应该是要操作的元素的指针类型的,对于字符串,它本身是字符的指针,它的指针就是字符的指针的指针,所以,当使用qsort对一个字符串数组排序,或者使用bsear原创 2009-04-28 20:09:00 · 1955 阅读 · 0 评论 -
使用qsort对二维字符数组排序疑难问题调试及解决过程
先说说我这个程序的场景。我程序中有一个二维数组,代码段如下: char files[101][64]; // files[i][0] sotres the length of the i-the file name 正如注释中说的,files[i][0]用来存储files[i]这个字符串的长度,字符串是从files[i原创 2009-07-14 19:40:00 · 2202 阅读 · 0 评论 -
gcc中使用scanf的一个小陷阱
这是在调试程序时发现的。如下一小段代码:#include stdio.h> int main() { short n, m; scanf("%d", &n); printf("n = %d/n", n); scanf("%d", &m); printf("n = %d, m = %d/n", n, m); return 0;}在命令行下分别使用原创 2009-06-04 11:34:00 · 3410 阅读 · 0 评论 -
C语言笔记五则
晚上讨论班回来,发现一些问题以前不清楚。具体来说:一:atexit注册的多个函数会形成一个链表。当用户调用exit后,被注册过的函数按照注册的反向顺序依次执行。另外,被atexit注册的函数除了类型必须为void (*)(void)外,就是一个普通的函数,在其中可以调用其它函数,例如在其中可以调用main函数,这一点应该原创 2009-06-05 08:24:00 · 1296 阅读 · 1 评论 -
递归下载FTP目录的win32 api实现和php实现
这里的递归下载指的是用recursive方式处理目录,即把该目录下的所有文件和子目录原样下载到本地。一个目录就是一棵树,子目录就是树中的内结点,文件和空目录就是树中的叶子结点,遍历树的算法就是深度优先和广度优先,因此写程序递归下载的思路也就是深度优先或者广度优先这两种思路。思路和代码实现都非常简单。这里最主要的地方在于FTP协议规定在一次session原创 2009-06-18 13:01:00 · 2662 阅读 · 0 评论 -
小于号重载须注意的问题——strict weak ordering
这是今天写程序中遇到的两个诡异的问题。我的IDE是VC++2005 ExpressiEdition。 第一个问题是关于map的。话不多说,以下20多行的C++代码重现了我遇到的问题: #include #include using namespace std;原创 2009-07-11 15:58:00 · 5767 阅读 · 1 评论 -
c中的数组名的指针类型解析
下面是用来输出变量信息的宏:#define typeof(typevar) / do { / string tmp; / cerr << "type of "#typevar" :"; / tmp = "c++filt -t "; / system((tmp + typeid(typevar).name()).c_str())原创 2009-11-28 19:52:00 · 1336 阅读 · 0 评论 -
旧事重提——const变量的存储区及修改权限
最近突然想起hjbolide在论坛上发过的这篇帖子:http://www.jluopen.org/bbs/viewthread.php?tid=129在帖子的最后,有这么一个很有趣的实验: const int a = 1; int *p = const_cast(&a); *p = 2; cout << “value a=”<< a <<原创 2009-12-11 14:06:00 · 8453 阅读 · 5 评论 -
在gcc中使用intel风格的内联汇编
很简单,内联汇编使用asm(“.intel_syntax noprefix/n”)声明一下,以后的内联汇编就可以用intel风格了,构建可执行文件时给gcc加上-masm=intel参数。先写一个小程序测试一下:#include int main() { int a = 3; asm(".intel_syntax noprefix/n");原创 2009-12-12 08:45:00 · 7684 阅读 · 1 评论 -
数据结构内存边界对齐的三条原则
以前看过这个问题并写程序测试,详见http://blog.youkuaiyun.com/jcwKyl/archive/2008/04/21/2311112.aspx#1290568。多谢YGone网友发现了其中的错误并在评论中指了出来,看到评论后又回头去看以前的那篇日志,发现其中还有很多错误,于是把这个问题重新整理总结了一下,结果写在这篇日志中。YGone网友发现的错误主要是以下数据结构:原创 2010-03-08 14:28:00 · 6779 阅读 · 3 评论 -
编译错误__sync_bool_compare_and_swap_4的解决
<br />做大文件的快速传输,需要调查一下bit torrent,下载了opentracker。<br />在编译libowfat的过程中,出现错误:<br />t.o: In function `main':<br />t.c:(.text+0x76): undefined reference to `__sync_bool_compare_and_swap_4'<br />t.c:(.text+0xa2): undefined reference to `__sync_bool_com原创 2010-12-16 10:56:00 · 16531 阅读 · 2 评论 -
GNU C对ISO标准的扩展——笔记(二)
Arrays of Variable Length变长数组,ISO C99标准中正式支持,在C89模式下作为GCC的扩展特性。变长数组即数组长度为变量,除此之外与普通数组在声明语法上没有区别。变长数组在声明处分配空间(在栈上分配空间而不是在堆上,这一点与函数alloca/_alloca相同,实际上用gdb调试发现,变长数组的空间分配就是通过调用alloca完成的),在作用域结束时自动收原创 2009-04-21 12:05:00 · 2596 阅读 · 0 评论 -
关于取struct成员的偏移
从朋友博客上看到有如下一个有趣的笔试题:struct s{int a;int b;char c[8];void* d;}mystruct;1,问&((struct s*)0)->d出现设么结果?2,这种类型的代码一般出现在什么情况下?答案是:1。16。2。取结构内元素的偏移时用。这种取结构内元素的偏移的写法是第一次看到,非常令人惊奇。为了更好地理解它,下面仔细地看看这是原创 2009-03-11 07:49:00 · 2041 阅读 · 0 评论 -
this指针作为函数隐含参数传递的方法
c++中的类成员函数中有个隐含的this指针做参数,参数传递过程原来是这样的(VC++6.0):测试代码:#include using namespace std;class A {public: void f() { cout }};int main() { A a; a.f(); return 0;}调试程序执行到a.f()处,查看汇编代码:a原创 2008-04-14 08:34:00 · 2920 阅读 · 0 评论 -
一个有趣的死循环程序
该程序来自csdn论坛:#include using namespace std;int main() { goto after; return 0;after: cout cout }这个程序在VC6.0下运行会出现死循环。看它编译后的汇编语句就能明白为什么会这样。原创 2008-04-14 08:35:00 · 1632 阅读 · 3 评论 -
关于 struct 和 union 存储时内存边界对齐的问题(二)
新的博客中好像修改以前写的博客的功能没有了。一个是在DEBUG版本中好像填充字节都是0xCC,0xCC是int 3中断指令的机器码。在release版本中,填充的字节好像没什么规律。下面是winnt.h中的那段代码:// winnt.h line 4947#ifndef _MAC#include "pshpack4.h" // 4 byte packi原创 2008-04-23 07:35:00 · 2175 阅读 · 0 评论 -
关于struct和union存储的内存字节对齐的问题
这是在读winnt.h头文件的源代码时发现了一段自己弄不明白的代码,继而牵扯到了结构体存储的内存边界对齐的问题。该问题在MSDN中说的比较少。以下是阅读MSDN中的一些重要信息:1.可以使用 #pragma pack 指令来指定对齐字节,该指令指定内存对齐字节的功能和编译器选项 /Zp 是等效的。2.#pragma指令对该指令之后的 struct 或 union 的声明有效。如果把这条指令原创 2008-04-21 10:56:00 · 4248 阅读 · 5 评论 -
从指向类成员函数的指针看指针的“类型”
事情起源于最近编程中出现的一个编译错误,该错误如下:D:/My Documents/My Projects/Pedump/SimplestDisassembler.cpp(23) : error C2440: initializing : cannot convert from bool (__thiscall CSimplestDisassembler::*)(void) to boo原创 2008-05-01 23:04:00 · 2037 阅读 · 4 评论 -
由C语言字符串解析方式带来的隐晦的程序设计问题
问题场景一:要格式化输出一行文本,格式如下:首先是一个字符串的16进制表示,这一部分最长32个字符,接着是与左边16进制数据对应的文本,一个看似正常的演示程序如下:#include stdio.h>#include string.h>int main() ...{ char part_text[32], part_hex[32], whole[128] = ...{0}; ch原创 2008-05-06 07:55:00 · 2066 阅读 · 0 评论 -
关于“编译时”和“运行时”
学习C++的过程中经常会遇到如“编译时类型检查”,“运行时类型识别”,“运行时错误”,“运行时类型转换”等多种说法,初看起来不难理解,然而细抠一下又不好理解,毕竟没发明过语言,没写过编译器,有时候思考的时候大脑又总是转不过这道弯,最近在enwiki上看到专门介绍runtime的资料,恍然大悟,感觉把“运行时”看成“写代码实现”的别名更好理解一些。运行时类型识别,也就是写代码实现类型识别的意思,运行原创 2008-11-03 10:57:00 · 1071 阅读 · 0 评论 -
STL中replace函数误用一例
这是在解JOJ 1170题目的时候遇到的问题,使用replace函数得不到期望结果,调试发现replace函数没有正确执行,查看STL中的源代码发现了问题。针对这个问题重新写一小段测试代码:#include #include #include #include using namespace std;int main() { int testA原创 2008-11-07 18:54:00 · 2777 阅读 · 3 评论 -
模板成员函数为什么不能是虚函数
《Thinking in C++》volume 2第五章有这么一句话: Member template functions cannot be declared virtual.Current compiler technology experts to be able to determine the size of a class’s virtual function table when t原创 2009-01-13 20:59:00 · 21004 阅读 · 2 评论 -
带有模板参数的函数指针
如果能定义一个带有模板参数的函数指针,例如:template void (*pf)(T);它就可以指向任何一个带有一个任何类型参数的函数了。但这种语法不被编译器支持。可以把这种类型的指针作为一个普通模板函数的参数来间接实现这种效果。例如:#include #include using namespace std;#define DF(func,type) /原创 2009-01-14 17:35:00 · 5071 阅读 · 0 评论 -
浅谈C/C++中的内存泄漏
对于一个c/c++程序员来说,内存泄漏是一个常见的也是令人头疼的问题。已经有许多技术被研究出来以应对这个问题,比如 Smart Pointer,Garbage Collection等。Smart Pointer技术比较成熟,STL中已经包含支持Smart Pointer的class,但是它的使用似乎并不广泛,而且它也不能解决所有的问题;Garbage Collection技术在Java中已经比较成转载 2009-01-16 23:11:00 · 1363 阅读 · 0 评论 -
使用位段实现整数的二进制形式输出
下面是简单的演示代码。可以将它封装成类使用。#include using namespace std;#define D(name) unsigned name:1union _U{public: struct { D(a0); D(a1); D(a2); D(a3); D(a4); D(a5); D(a6); D(a原创 2009-02-02 00:36:00 · 1347 阅读 · 0 评论 -
float与double:坚决弃float用double一例
如下9行代码,输出结果说明了问题:#include int main() { float f = 0.01; int i = 1800; printf("%d/n", (int)(f*i)); printf("%f/n", f*i); return 0;}输出:1718.000000编译上述程序时在float f = 0.01语句处会出现一个warning: truncation from原创 2009-02-25 11:16:00 · 1287 阅读 · 0 评论 -
linux编程获取本机IP地址的三种方法
<br />这是一项不太清晰而且没有多大意义的工作。一个原因是网络地址的设置非常灵活而且都是允许用户进行个性化设置的,比如一台计算机上可以有多块物理网卡或者虚拟网卡,一个网卡上可以绑定多个IP地址,用户可以为网卡设置别名,可以重命名网卡,用户计算机所在网络拓扑结构未知,主机名设置是一个可选项并且同样可以为一个计算机绑定多个主机名等,这些信息都会有影响。脱离了网络连接,单独的网络地址没有任何意义。编程中遇到必须获取计算机IP的场景,应该考虑将这一选项放到配置文件中,由用户自己来选择。<br /原创 2011-04-14 20:33:00 · 36295 阅读 · 1 评论