
C/C++
wade23
这个作者很懒,什么都没留下…
展开
-
[精彩] char[0], sizeof和struct padding
我想举一个自己最近在项目中犯的错误来说明要踏踏实实做人,不要做装B青年 :( 在代码中,我需要在一个library和一个daemon之间通过socket传送数据包,包的格式定义如下(为了简化,我就用最简单的数据类型举例):typedef struct { int head; int size; //指明整个包的长度 char reply;转载 2009-09-02 10:38:00 · 1377 阅读 · 0 评论 -
解析c语言的复杂声明实践
看了那篇文章,总结一下,解析复杂声明其实就是从最里面的未定义标识符开始,左边和右边同时找一对符号来配对,不断向外扩展,最后完成解析。int (*(*func)[5][6])[7][8];func是个指针,这个指针指向什么呢。那我们就可外围,左边和右边找一对符号:* [5][6],这表示一个二维数组,数组元素是指针。所以func指向的就是这个数组啦。但是这个数组元素指针指向什么我们还是不知道的,原创 2009-09-14 18:45:00 · 390 阅读 · 0 评论 -
堆和栈的区别
这篇是优快云的 laomai(老迈)写的,虽然一些细节有异议,但是还是讲得比较清楚的。===================== 一、预备知识—程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 2、堆区(heap转载 2009-09-14 15:58:00 · 478 阅读 · 0 评论 -
指针赋值时的相容性
这个标题不知道算不算确切,今天从《c专家编程》看起,然后发散到不知什么地方去了,乱乱的看了一堆东西。还是先从《c专家编程》说起吧。今天看了一个开头,主要是在1.9节的一个问题。foo(const char** p) {}main(int argc, char ** argv){ foo(arvg);}会出现警告:参数和原型不匹配。也就是说char **和const char原创 2009-09-15 23:24:00 · 883 阅读 · 0 评论 -
多叉树转二叉树
多叉树的根结点为二叉树的根,多叉树的结点的第一个儿子变成二叉树对应结点的左孩子,多叉树的结点的右兄弟变成二叉树种该结点的右孩子。代码如下:C语言: 01 #include 02 #include 03 #include 04 #include 05 06 typedef struct TreeNode{ 07 int child_count; 08 int原创 2009-10-09 17:33:00 · 6907 阅读 · 0 评论 -
x++ + x++
考试的一道题目,按理说结果应该是依赖于编译器,但是题目也没说。假定是在gcc的环境下吧。总的解题步骤是: 1.先算所有的前增量操作,即先算所有的++x。 2.再取含有x的表达式的值。 3.执行后增量操作,即算x++。 如: int x=9,y; y = x++ + x++; 里面有两个含有x的表达式(x++),取值是9,所以y的值就是18,x最后是11. 若 y = ++x + +原创 2009-10-23 14:55:00 · 2482 阅读 · 0 评论 -
C语言的inline
C语言的inline转以前我用Docbook写的一篇关于C语言inline关键字使用的文章。唉,要是能用docbook直接写Blog就好了。用得越多发现Docbook这个东西真是越好用啊~~ 本文介绍了GCC和C99标准中inline使用上的不同之处。inline属性在使用的时候,要注意以下两点:inline关键字在GCC参考文档中仅有对其使用在函数定义(D转载 2010-03-05 18:18:00 · 433 阅读 · 0 评论 -
常用ansi控制码
下面是搜到的常用ansi控制码。但是其中保存,恢复光标位置的控制码我一直没用成功。我先用/033[s 保存当前的光标位置,再用/033[x;yH来设定光标位置,最后恢复光标位置/033[u ,但是始终恢复不到原来那个位置。搞不懂。 BBS支持ANSI/3.64控制码标准,ANSI控制码均以Esc[作为控制码的开始标志。 BBS中ESC字符的输入方法是[ESC]+[ESC],在编辑器原创 2009-12-31 11:05:00 · 3013 阅读 · 0 评论 -
ansi控制码
最近在搞终端的咚咚,涉及到ansi控制码的问题,网上搜了一通,也学到不少。如果你telnet到一个linux服务器上,然后输入命令,比如vi test.c,然后客户端可以看到test.c文件的内容,如果抓包的话,可以看到数据包里面不止包括test.c的内容,还有一些看似乱码的东西。比如下面这种: int num, fd;/033[22;9Hchar m[6000];/033[23;9Hchar原创 2009-12-31 10:57:00 · 2021 阅读 · 0 评论 -
二维数组作为参数传递
二维数组作为函数参数的一种形式:func(int a[][10]),这种形式我是知道的。但是要写死第二维的长度,不太灵活。搜了一下: .静态二维数组作为函数参数传递 如果采用上述几种方法动态分配二维数组,那么将对应的数据类型作为函数参数就可以了。这里讨论静态二维数组作为函数参数传递,即按照以下的调用方式: int a[2][3]; func(a); C语言中将静态原创 2010-05-10 20:23:00 · 981 阅读 · 0 评论 -
c语言的转义字符
今天改代码的时候发现一个转义字符/012,莫名的很。上网搜了一下: 转义字符是C语言中表示字符的一种特殊形式。通常使用转义字符表示ASCII码字符集中不可打印的控制字符和特定功能的字符,如用于表示字符常量的单撇号( ),用于表示字符串常量的双撇号( ")和反斜杠( /)等。转义字符用反斜杠/后面跟一个字符或一个八进制或十六进制数表示。 转义字符 意义 ASCII码值(十进制) /a原创 2010-05-10 20:12:00 · 812 阅读 · 0 评论 -
栈的默认大小
今天看了几篇讨论堆和栈的文章,里面讲到栈的默认大小可能是1m,也可能是2m,好奇之下试试。int main (int argc, char *argv[]){ int tmp[1000*256*2+1000*3] = {0};}大概就是2.3m吧,如果再大,就会出现5 [main] Test 3204 handle_exceptions: Except原创 2009-09-14 16:17:00 · 8839 阅读 · 1 评论 -
堆和栈区别2
这是另一篇讨论堆和栈的,更深入些=====================五大内存分区 在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区。 栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。 堆,就是那些由new分配的转载 2009-09-14 16:14:00 · 721 阅读 · 0 评论 -
结构体零长度数组的意义
在一些 C 语言编写的代码中,有时可以看到如下定义的结构: typedef struct user_def{ char * name; int length; char bytes[0];} user_def_t;这个 bytes 是什么意思?我们知道 0 == sizeof(bytes),那么 bytes 仅仅是为了定义结构的尾地址吗?不是的。原创 2009-09-02 13:43:00 · 3043 阅读 · 0 评论 -
sizeof(struct)内存分配分析
请看下面的结构: struct MyStruct { double dda1; char dda; int type; };对结构MyStruct采用sizeof会出现什么结果呢?sizeof(MyStruct)为多少呢?也许你会这样求:sizeof(MyStruct)=sizeof(double)+sizeof(char)+sizeof(int原创 2009-09-02 10:01:00 · 885 阅读 · 0 评论 -
运算符#和##
运算符#和## TAG:预编译和宏定义,运算符#和##TEXT:在ANSI C中为预编译指令定义了两个运算符——#和##。# 的作用是实现文本替换,例如#define HI(x) printf("Hi,"#x"/n");void main(){HI(John);}程序的运行结果Hi,John在预编译处理的时候, "#x"的作用是将x替换为所代转载 2009-09-04 09:58:00 · 601 阅读 · 0 评论 -
C/C++中的日期和时间
我的总结:这篇对时间的描述应该是比较完整了。要注意的是clock()函数来求一段时间的话,只能在一个进程内部求,因为它是以进程起始点为标准的。gettimeofday()可以用在多个进程间,因为它是以1970年1月1日为标准的。但是gettimeofday有个问题就是它存时间的数据字段是个long型,在32位系统里面,最多可以表示68年的一个时间间隔,也就是说如果在2039年以后用这个函数,得到的转载 2009-09-04 17:27:00 · 729 阅读 · 0 评论 -
整数溢出
gettimeofday()引出的问题。因为用long存秒数最多能存68年,如果超过这个时间段就会产生溢出。比如,int i = INT_MAX,i++,则i就会溢出。这时i的二进制值就是1000……0,因为负数使用补码表示,1000……0取反(不包括符号位)再加1,i的值实际上就是负的INT_MAX+1。下面转的这篇文章对整数溢出讲得比较清楚。======================转载 2009-09-07 09:27:00 · 2312 阅读 · 0 评论 -
#error指令
#error指令 TAG:预编译和宏定义,ANSI C,#errorTEXT:语法格式如下:#error token-sequence其主要的作用是在编译的时候输出编译错误信息token-sequence,从方便程序员检查程序中出现的错误。例如下面的程序#include "stdio.h"int main(int argc, char转载 2009-09-04 10:01:00 · 939 阅读 · 0 评论 -
sprintf的一点问题
sprintf使用参数 %s 时,是把字符串放到指定的缓冲区,字符串要以“/0”结尾,否则会导致不可预料的行为。如这些: char name[20]; char temp1[5] = "abcde"; memset(name,0,sizeof(name)); sprintf(name,"%s ",temp1);name里面可能是“abcde”,原创 2009-09-08 18:41:00 · 870 阅读 · 0 评论 -
指针+1的问题
指针 + 1 并不是指针代表的地址值 + 1. 指针变量加1,即向后移动1 个位置表示指针变量指向下一个数据元素的首地址。而不是在原地址基础上加1。至于真实的地址加了多少,要看原来指针指向的数据类型是什么。 char a = a;char *p = &a;cout输出:0012FF33 0012FF34p指向的是一个字符,p+1就是移动一个字符大小,一个字符就是一个字原创 2009-09-12 15:14:00 · 9924 阅读 · 3 评论 -
解析c语言的复杂声明
以前不知道怎么看那种复杂的声明,看了这篇文章就清楚多了===================================上一章费那么多唇舌讨论C语言的声明,其实目的都是为了这一章,期望读者通过对C语言声明形式的详细了解,树立声明嵌套的观念,因为C语言所有复杂的指针声明,都是由各种声明嵌套构成的。如何解读复杂指针声明呢?右左法则是一个既著名又常用的方法。不过,右左法则其实并不是C标准里面转载 2009-09-14 18:01:00 · 618 阅读 · 0 评论 -
内存分配详解、指针与数组[C++][内存管理]
这篇讲得比较基本。==============程序员们经常编写内存管理程序,往往提心吊胆。如果不想触雷,唯一的解决办法就是发现所有潜伏的地雷并且排除它们,躲是躲不了的。本文的内容比一般教科书的要深入得多,读者需细心阅读,做到真正地通晓内存管理。 内存分配方式 (1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,st转载 2009-09-14 15:47:00 · 646 阅读 · 0 评论 -
sizeof 和 strlen
sizeof 包括字符串后面的/0, strlen不包括后面的/0,比如sizeof("abc") 值是 4 ,而strlen("abc") 值是 3 。原创 2010-05-10 20:24:00 · 439 阅读 · 0 评论