随笔分类 - 语言之美
摘要:多态性可分为两类:静态多态和动态多态。函数重载和运算符重载实现的多态属于静态多态,动态多态性是通过虚函数实现的。每个含有虚函数的类有一张虚函数表(vtbl),表中每一项是一个虚函数的地址, 也就是说,虚函数表的每一项是一个虚函数的指针。没有虚函数的C++类,是不会有虚函数表的。两张图:简单例子: 1...
阅读全文
摘要:C语言中的很多函数的入参被定义为可变参数,最典型的int printf (const char * fmt, ...)要对其中的可变参数进行处理,就要用到va_list类型和 VA_START, VA_END, VA_ARG 宏 ,需要包含头文件利用va族函数对不定参数进行解析的过程所示如下: 1 int my_printf(const char * fmt, ...) 2 { 3 va_list struAp; 4 va_start(struAp, fmt); 5 6 for (; *fmt; ++fmt) 7 { 8 if(*fmt != ...
阅读全文
摘要:我们看下面的函数,函数体中只有一行语句: double Average(double total, int number){ return total/number;} 定义这么简单的函数有必要吗?实际上,它还是有一些优点的:第一,它使程序更可读;第二,它使这段代码可以重复使用。但是,它也有缺点:当它被频繁地调用的时候,由于调用函数的开销,会对应用程序的性能(时间+空间效率,这儿特指时间)有损失。例如,Average在一个循环语句中重复调用几千次,会降低程序的执行效率。那么,有办法避免函数调用的开销吗?对于上面的函数,我么可以把它定义为内联函数的形式:inline double Ave...
阅读全文
摘要:switch...case与if...else的根本区别在于,switch...case会生成一个跳转表来指示实际的case分支的地址,而这个跳转表的索引号与switch变量的值是相等的。从而,switch...case不用像if...else那样遍历条件分支直到命中条件,而只需访问对应索引号的表项从而到达定位分支的目的。 具体地说,switch...case会生成一份大小(表项数)为最大case常量+1的跳表,程序首先判断switch变量是否大于最大case 常量,若大于,则跳到default分支处理;否则取得索引号为switch变量大小的跳表项的地址(即跳表的起始地址+表项大小*索引...
阅读全文
摘要:size _t为了增强程序的可移植性,便有了size_t,不同系统上,定义size_t可能不一样。经测试发现,在32位系统中size_t是4字节的,在64位系统中,size_t是8字节的,这样利用该类型可以增加程序移植性。size_t的定义它的定义在/usr/include/linux/types.h typedef_kernel_size_tsize_t;跟体系结构相关而__kernel_size_t定义在/usr/include/asm/posix_types.h安装的是内核的源码asm-i386/posix_types.htypedef unsigned int __kernel_siz
阅读全文
摘要:一直存在比较模糊的概念,因此用一个例子强化记忆。 linux x86 gcc3.2.3 AT&T格式的汇编 代码如下: void fun() { int a = 'A'; } void main() { int b; fun(); return; } 开始调试 [sanool@sanool ex2]$ gdb a.out GNU gdb Red Hat Linux (6.0post-0.20031117.6rh) Copyright 2003 Free Software Foundation, Inc. GDB is free software, covered by
阅读全文
摘要:1.memmove函数原型:void *memmove(void *dest, const void *source, size_t count)返回值说明:返回指向dest的void *指针参数说明:dest,source分别为目标串和源串的首地址。count为要移动的字符的个数函数说明:memmove用于从source拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。2.memcpy函数原型:void *memcpy(void *dest,const void *source,size_tcount);返
阅读全文
摘要:用途一: 定义一种类型的别名,而不只是简单的宏替换。可以用作同时声明指针型的多个对象。比如: char* pa, pb; // 这多数不符合我们的意图,它只声明了一个指向字符变量的指针, // 和一个字符变量; 以下则可行: typedef char* PCHAR; // 一般用大写 PCHAR pa, pb; // 可行,同时声明了两个指向字符变量的指针 虽然: char *pa, *pb; 也可行,但相对来说没有用typedef的形式直观,尤其在需要大量指针的地方,typedef的方式更省事。用途二: 用在旧的C代码中(具体多旧没有查),帮助struct.以前的代码中,...
阅读全文
摘要:在所有的预处理指令中,#Pragma 指令可能是最复杂的了,它的作用是设定编译器的状态或者是指示编译器完成一些特定的动作。#pragma指令对每个编译器给出了一个方法,在保持与C和C ++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。其格式一般为: #Pragma Para其中Para 为参数,下面来看一些常用的参数。(1)message 参数。 Message 参数是我最喜欢的一个参数,它能够在编译信息输出窗口中输出相应的信息,这对于源代码信息的控制是非常重要的。其使用方法为:#Pragma message(“消息文
阅读全文
摘要:int main(int argc, char *argv[]){ short a = 0xffff; printf("a = 0x%x\n", a); if(a == 0xffff) { printf("Just Test\n"); } return 0;}最后输出的结果是 a = 0xffffffff原因如下:1.%x 表示要输出无符号整数(unsigned int)的十六进制形式2.当有符号类型向更大长度类型转换时,如果首位为1,则前面全部补全为1,如首位为0,则前面全部补全为0预期的打印Just Test不会被打出来,因为:在比较时a被强制转换成
阅读全文
摘要:C语言中最棘手问题的当属指针了,不过这也是C的精华所在。指针也是一种变量,区别在于他的值是一个内存地址。32位机器上,指针变量占用四个字节。往往你觉得你把指针弄的很透彻了,但你还是会做错题目,或许因为粗心,或许自己混淆了,总之指针问题真的很绕。最近笔者在看「程序员求职成功之路」,书中伊始讲的就是C语言指针,看完之后获益匪浅,特在此总结一下。1.先看一道经典的指针题目: #include <stdio.h> int main() { int a[5][10]; printf("%d,%d,%d\n",a,a+1,&a+1); return 0; } 输出结
阅读全文
摘要:PS:原文翻译的有些地方不太确切,尤其是对于第7点static的使用的翻译容易引起误解,故稍做调整,如有妥之处,还请谅解!任何代码的美丽不仅在于找到一个给定的问题的解决方案,还在它的简单性,有效性,紧凑性和效率(内存)。设计的代码比实际执行更难 。因此,每一个程序员当用C语言开发时,都应该保持这些基本的东西在头脑中。 本文向你介绍规范你的C代码的10种方法。 1. 避免不必要的函数调用 考虑下面的2个函数:view sourceprint?void str_print( char *str ) { int i; for ( i = 0; i < strlen ( str ); i++){
阅读全文

浙公网安备 33010602011771号