
C/C++编程
文章平均质量分 81
海风林影
彪悍的人生可以没有妹,但是不能没有技术!!
展开
-
深入探索C语言之结构体(struct)
结构(struct)就是一种把一些数据项组合在一起的数据结构,其他语言把它称做为记录(record)。语法为将需要组合的内容放在花括号中,前面加上一个关键字struct,如下:struct {内容...};1. 怎样定义结构体变量:举个具体的例子,如将在校学生的信息定义为一个结构体,信息内容包括学生的姓名(string)、学号(long)、年龄(int)等,就可以声明如下:原创 2012-04-11 15:34:38 · 1773 阅读 · 1 评论 -
五个好的C语言编程实践
前几天,我看到一个关于编程语言的调查,我发现到目前为止,C 编程语言在全球开发者中仍然稳居前三。如此多的代码使用C来编写,我想分享我多年学习总结的一些好的C语言编程实践。不要使用gets()和strcpy()再也不要使用诸如gets()、strcpy()、sprintf()等等这些函数,这已经是一个广为人知的一个事实,但这些函数仍然在库中,以用来支持那些已经使用这些函数的代码。如果原创 2013-05-22 19:08:37 · 3858 阅读 · 1 评论 -
Linux Kernel 代码艺术——编译时断言
本系列文章主要写我在阅读Linux内核过程中,关注的比较难以理解但又设计巧妙的代码片段(不关注OS的各个模块的设计思想,此部分我准备写在“深入理解Linux Kernel” 系列文章中),一来通过内核代码复习一下C语言及汇编语言的语法,二来学习内核开发大牛们书写代码的风格及思路。在内核文件 include/linux/bug.h中,有下面两行的宏定义:1 2原创 2013-07-15 21:14:16 · 2492 阅读 · 2 评论 -
C语言中结构体赋值的讨论
今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题。那么就总结一下C语言中结构体赋值的问题吧:结构体直接赋值的实现下面是一个实例:#include struct Foo { char a; int b; double c原创 2013-07-23 22:04:35 · 32638 阅读 · 1 评论 -
Linux Kernel代码艺术——数组初始化
前几天看内核中系统调用代码,在系统调用向量表初始化中,有下面这段代码写的让我有点摸不着头脑:const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = { /* * Smells like a compiler bug -- it doesn't work * when the & below is rem原创 2013-09-26 15:18:14 · 3210 阅读 · 0 评论 -
GCC 中零长数组与变长数组
前两天看程序,发现在某个函数中有下面这段程序:int n; //define a variable nint array[n]; //define an array with length n在我所学的C语言知识中,这种数组的定义在编译时就应该有问题的,因为定义数组时,数组的长度必须要是一个大于0的整型字面值或定义为 const 的常量原创 2013-10-27 10:19:51 · 2098 阅读 · 0 评论 -
C 语言中 setjmp 和 longjmp
在 C 语言中,我们不能使用 goto 语句来跳转到另一个函数中的某个 label 处;但提供了两个函数——setjmp 和 longjmp来完成这种类型的分支跳转。后面我们会看到这两个函数在处理异常上面的非常有用。setjmp 和 longjmp 使用方法我们都知道要想在一个函数内进行跳转,可以使用 goto 语句(不知怎么该语句在中国学生眼中就是臭名昭著,几乎所有国内教材都一刀原创 2013-11-03 15:56:56 · 1607 阅读 · 1 评论 -
浅谈 C++ 中的 new/delete 和 new[]/delete[]
在 C++ 中,你也许经常使用 new 和 delete 来动态申请和释放内存,但你可曾想过以下问题呢?new 和 delete 是函数吗?new [] 和 delete [] 又是什么?什么时候用它们?你知道 operator new 和 operator delete 吗?为什么 new [] 出来的数组有时可以用 delete 释放有时又不行?…如果你对这些问题都有疑问的话,原创 2014-03-17 22:49:32 · 160945 阅读 · 45 评论 -
C/C++ 中头文件相互包含引发的问题
C/C++ 中头文件相互包含引发的问题今天下午遇到一个头文件相互包含而导致的编译问题,花了我不少时间去调试没找到问题,最后晚上跟师兄讨论不少时间,突然有所顿悟!问题重现我把问题脱离于项目简单描述一下:我写了一个函数 bool func(ClassA* CA) 需要加到项目中,我就把这个函数的声明放到 head1.h 中,函数参数类型 ClassA 定义在另一个头文件 hea原创 2014-08-16 00:39:34 · 68930 阅读 · 15 评论 -
为什么 C++ 中成员函数指针是 16 字节?
当我们讨论指针时,通常假设它是一种可以用 void * 指针来表示的东西,在 x86_64 平台下是 8 个字节大小。例如,下面是来自 维基百科中关于 x86_64 的文章 的摘录:Pushes and pops on the stack are always in 8-byte strides, and pointers are 8 bytes wide.从 CPU 的角翻译 2014-12-09 22:37:13 · 1641 阅读 · 0 评论 -
从IEEE754标准谈C语言浮点数据类型
先看下面几个问题,如果你能准确地回答,那么此篇文章将不适合你:计算机中怎样表示浮点数的,与整型的表示方法有什么不同? 32位精度的float类型和64位精度的double类型能表示浮点数最大范围是多少? 该C语言语句 printf("%d\n", 2.5); 输出结果是什么,为什么? 我先说在此之前我如果回答,答案如下:计算机中有符号整型采用补码进行表示,浮点型怎么表示没想过原创 2012-12-07 10:55:09 · 4777 阅读 · 0 评论 -
建立自己的函数调用帧
本文从最简单的打印“hello world!”的C程序开始,写出其汇编程序(在汇编中使用C库函数),讲解怎样建立自己的函数调用帧,接着使用jmp指令替代call完成函数的调转与返回。在linux内核中这种技巧被大量使用,最后举出内核中使用到的两个实例。首先,下面的C程序完成的功能,相信大家学大多数语言,都是用来讲解的第一个示例://helloworld1.c #include原创 2012-11-26 22:30:09 · 1079 阅读 · 0 评论 -
1.仔细区别POINTERS 和 REFERENCES
没有所谓的null reference: 若有一个变量有可能代表一个对象,也可能不代表任何对象,应该使用pointer; 如果这个变量必须代表一个对象,即不允许这个变量为null,则应该使用reference。 因此,reference必须要有初始化,但pointer就没有此限制(不过,无初始化的pointer风险很高)。原创 2012-04-14 16:43:16 · 877 阅读 · 0 评论 -
2. 最好使用C++转型操作符
旧式的C转型方式,几乎允许你将任何类型转换为任何其它类型,有其自身的缺陷,表现在以下两方面:不能更精确地指明其转型的意图。如将一个pointer-to-base-class-object 转型为一个pointer-to-derived-class-object(改变一个对象的类型)和将一个pointer-to-const-object转型为一个pointer-to-non-co原创 2012-04-14 18:02:47 · 1087 阅读 · 0 评论 -
8. 了解各种不同意义的new 和 delete
C++中关于new 的形态主要有三种:new operator, operator new, placement new三者的用法有着不同,注意区别适用的条件:new operator:new 操作符,和C++语言其它操作符(如+, -, ->, ::....)一样,是由语言内建的,总是完成相同的事情,程序员不能改变其意义。如下为new的一种用法:string *ps = ne原创 2012-04-15 14:10:54 · 1503 阅读 · 0 评论 -
6. 区别increment/decrement操作符的前置(prefix)和后置(postfix)形式
C++中允许++ 和-- 操作符的前置和后置两种形式具有重载的能力。而重载是以参数类型来区分的,然而不论是++ 还是 -- 的前置或后置均没有参数,为了区分这两种不同的操作,只好让后置式有一个int自变量,并且在它调用的时候,编译器默认给该int指定一个0值。下面的例子是使char型也能进行++ 和 -- 的运算:class Char{public: Char(char); Cha原创 2012-04-16 16:27:52 · 1233 阅读 · 0 评论 -
5. 对定制的“类型转换函数”保持警觉
C++中允许编译器在不同类型中执行隐式转化,例如默默地将char转化为int,将short转化为double等等,这些是语言提供的。现在当你写自己的类型时,你可以选择是否提供某些函数,供编译器用作隐式类型转化之用。如定义一个类类型,是否允许其它类型转化为此类类型,我们可以操控的。可以通过两种函数允许编译器执行这样的隐式转化:单自变量constructor 和隐式类型转化操作符。单自变量co原创 2012-04-15 19:29:43 · 802 阅读 · 0 评论 -
7. 千万不要重载&& ,|| 和,操作符
C/C++语言对于逻辑表达式具有“逻辑短路”的性质,即一旦确定了真假值,表达式中即使有尚未检查的部分,都将返回。如:char *p;if ((p != NULL) && printf("%c", *p)) ... //(1) int rangeCheck(int index){ if ((index upperBound)原创 2012-04-16 17:39:53 · 1000 阅读 · 0 评论 -
16. 谨记80-20规则
80-20 法则一个程序 80% 的资源用于20% 的代码身上。这里的资源包括:执行时间、内存消耗、磁盘访问、维护成本.....这说明了:软件的整体性能几乎总是由其构成要素(代码)的一小部分决定。也给我们指明了提升软件性能的一个方向:我们只要找到这20%的代码,并进行相应的优化,那么我们程序的运行速度就可以有较大的提高。而怎样找到这20%的代码,有两种不原创 2012-04-17 14:26:29 · 1460 阅读 · 0 评论 -
19. 了解临时对象的来源
什么是临时对象?C++真正的临时对象是不可见的匿名对象,不会出现在你的源码中,但是程序在运行时确实生成了这样的对象。通常出现在以下两种情况:(1)为了使函数调用成功而进行隐式类型转换的时候。传递某对象给一个函数,而其类型与函数的形参类型不同时,如果可以通过隐式转化的话可以使函数调用成功,那么此时会通过构造函数生成一个临时对象,当函数返回时临时对象即自动销毁。如下例:原创 2012-04-18 23:00:27 · 1712 阅读 · 0 评论 -
20. 协助完成“返回值优化(RVO)”
[19]最后曾提到了在函数通过传值方式(by value)返回一个对象时,不可避免地要生成一个临时对象,这会严重影响到程序的效率,如下例计算两个分式的乘积:class CRational{public: CRational(int numerator, int denominator) { this->numerator = numerator;原创 2012-04-19 11:50:31 · 1046 阅读 · 1 评论 -
GNU Readline 库及编程简介
用过 Bash 命令行的一定知道,Bash 有几个特性:TAB 键可以用来命令补全↑ 或 ↓ 键可以用来快速输入历史命令还有一些交互式行编辑快捷键:C-A / C-E 将光标移到行首/行尾C-B / C-F 将光标向左/向右移动一个位置C-D 删除光标下的一个字符C-K 删除光标及光标到行尾的所有字符C-U 删除光标到行首的所有字符...同样的操作在很多交互式程序都有类似的原创 2014-12-09 22:22:03 · 5378 阅读 · 0 评论