C

声明

某些资源由网上整理而来,这里不做详细出处

Basic Definition

C history

C的由来

C语言是由UNIX的研制者DennisRitchie和KenThompson于1970年研制出的B语言的基础上发展和完善起来的.

 

C的特点

C语言是一种面向过程的语言,同时具有汇编语言和高级语言的优点.C语言可以广泛应用于不同的操作系统,如UNIX,DOS,Windows及Linux等.

 

C的发展

1973年,C语言第一次被用来编写操作系统(Unix)的内核.

Dennis Ritchie和Brian Kernighan在1978年出版了<<C程序设计语言>>(The CProgramming Language,经常简称为"白皮书"或"K&R").K&R C

 

1983年,美国国家标准委员会(ANSI)对C语言进行了标准化,颁布了第一个C语言标准草案.后来于1987年又颁布了另一个C语言标准草案. 最终1988年10月颁布了ANSI标准X3.159-1989.一年左右以后,该标准被接受为国际标准,ISO/IEC 9899:1990.称为C89或C90.

 

1999年又出版了最新的C语言标准ISO9899:1999.并在2000年3月被ANSI采用.称为C99.

 

C的标准化

由C的发展可知,C的标准化主要有三:

一.K&RC, 由TheC Programming Language这本书所定义的C语言.

二.ANSIC,也可称C89,由X3.159-1989(ISO/IEC9899:1990)所定义的C语言.

三.C99,由ISO9899:1999所定义的C语言

 

但是各个公司对C99的支持所表现出来的兴趣不同。当GCC和其它一些商业编译器支持C99的大部分特性的时候,微软和Borland却似乎对此不感兴趣。

 

Linux C

CC: 老的unix系统的CC程序叫做C  Compiler

 

GCC: Gnu  Compiler   Collection.因为gcc包含很多编译器(   C,  C++,   Objective-C,   Ada,  Fortran,and   Java),所以GCC是一个Gnu的编译器的集合

 

编译过程

可执行程序生成的四个过程:预处理-编译-汇编-链接

1) 预处理(Pre-processing)

在该阶段,编译器将C源代码中的包含的头文件如stdio.h编译进来,用户可以使用gcc的选项”-E”进行查看。

2)  编译阶段(Compiling)

第二步进行的是编译阶段,在这个阶段中,Gcc首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,Gcc把代码翻译成汇编语言。用户可以使用”-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。

3)  汇编阶段(Assembling)

汇编阶段是把编译阶段生成的”.s”文件转成二进制目标代码.

4) 链接阶段(Link)

在成功编译之后,就进入了链接阶段。

 

libc/Glibc/Glib区别

libc指C函数库,这是一个通称。

 

GNU libc就是glibc。

glibc是linux下面c标准库的实现,当然linux下面的标准c库不仅有这一个,如uclibc和klibc,但是glibc无疑是用得最多的。

glibc2是glibc的version2(第二版)。

 

glib是Gtk+库和Gnome的基础。glib可以在多个平台下使用,比如Linux、Unix、Windows等。GLib为许多标准的、常用的C语言结构提供了相应的替代物。GLib是一组较高层的函数库,其中定义了好多有用的数据结构,如单(双)向链表,可变长的数组等,Hash,线程池等有用的东西,在linux中glib是建立在glibc之上的。

glib2是glib的第二版。

C语言经典书籍

1、C语言初级教材

 

(1)《C程序设计语言》(TheC Programming Language )

 

    作者:Brian W.Kernighan,  Dennis M.Ritchie

 

    简介:本书是由C语言的设计者Brian W. Kernighan和DennisM. Ritchie编写的

 

一部介绍标准C语言及其程序设计方法的权威性经典著作。一本必读的程序设计语言方面的参考书。

 

(2)《CPrimer Plus中文版》(CPrimer Plus)

 

    作者:Stephen Prata

 

    简介:作为核心计算机技术成熟、完整的参考书籍,PrimerPlus系列历经十数年不衰,通过学习《CPrimer Plus(第五版)中文版》,你将奠定坚实的C编程基础。

 

(3)《C和指针》(Pointerson C)

 

    作者:Kenneth A.Reek

 

    简介:本书提供与C语言编程相关的全面资源和深入讨论。全书覆盖了数据、语句、操作符和表达式、指针、函数、数组、字符串、结构和联合等几乎所有重要的C编程话题。书中给出了很多编程技巧和提示。

 

2、C语言进阶书籍

 

(1)《C陷阱与缺陷》(CTraps and Pitfalls)

 

    作者:Andrew Koenig

 

    简介:作者以自己1985年在Bell实验室时发表的一篇论文为基础,结合自己的工作经验扩展成为这本对C程序员具有珍贵价值的经典著作。本书的出发点不是要批判C语言,而是要帮助C程序员绕过编程过程中的陷阱和障碍。

 

(2)《C专家编程》(ExpertC Programming )

 

    作者:Perter Van Der LinDen

 

    简介:展示了最优秀的C程序员所使用的编码技巧。 书中C的历史、语言特性、声明、数组、指针、链接、运行时、内存以及如何进一步学习C++等问题进行了细致的讲解和深入的分析。全书撷取几十个实例进行讲解,对C程序员具有非常高的实用价值。

 

(3)《C语言编程常见问题解答》(CProgramming : Just the Faqs )

 

    作者:Paul S.R.Chisholm 等        

 

    简介:这是一本专门解答c语言编程常见问题的著作。书中所覆盖的内容相当广泛,并附有大量鲜明的例子。

Important Point

C优先级

1   ()  [] .  →

2   !  ~   -(负号)++  --  &(取变量地址)*   (type)(强制类型)    sizeof

3   * / %

4   + -

5   >><< 

6   > >= <<=

7   == !=  

8   & 

9   ^  

10  |  

11  &&

12  ||

13  ?:

14   =  += -=  *=  /=   %=  |=  ^=   &=   >>=  <<=

15  ,

就着多吧   结合性:2  13  14  是从右至左  其他都是  从左至右

 

Const vs volatile

const修饰的对象其值不能改变,而volatile修饰的对象其值可以随意地改变,也就是说,volatile对象值可能会改变,即使没有任何代码去改变它。在这一点上,最典型的例子就是内存映射的设备寄存器和多线程中的共享对象。

使用volatile约束符可以阻止编译器对代码过分优化防止出现一些你意想不到的情况,达不到预期的结果;过频地使用volatile很可能会增加代码尺寸和降低性能。

volatile定义的对象其内容可能会忽然的变化。换句话讲,如果你定义了一个volatile对象,就等于你告诉编译器该对象的内容可能会改变,即使代码中没有任何语句去改变该对象。编译器访问非volatile对象和volatile对象的方式很不一样。对于前者(经优化后),它先将非volatile对象的内容读到CPU寄存器中,等操作CPU寄存器一段时间后,才最终将CPU寄存器的内容写回volatile对象。然而,对于volatile对象就没有这种优化操作。这时候编译器有些“笨”,代码要求它读取或写入volatile,它就马上如实地去做。

大端(BigEndian)与小端(LittleEndian)

    对于跨越多个字节的对象,一般它所占的字节都是连续的,它的地址等于它所占字节最低地址。(链表可能是个例外, 但链表的地址可看作链表头的地址)。

 

考虑一个W位的整数,它的各位表达如下:[Xw-1, Xw-2, ... , X1, X0],它的

    MSB (MostSignificant Byte, 最高有效字节)为 [Xw-1, Xw-2, ...Xw-8];

    LSB (LeastSignificant Byte, 最低有效字节)为 [X7,X6,..., X0]。

其余的字节位于MSB, LSB之间。

 

如果LSB在MSB前面, 既LSB是低地址, 则该机器是小端;反之则是大端。

 

DEC (Digital Equipment Corporation,现在是Compaq公司的一部分)和Intel的机器(X86平台)一般采用小端。

IBM,Motorola(Power PC),Sun的机器一般采用大端。

当然,这不代表所有情况。有的CPU即能工作于小端, 又能工作于大端, 比如ARM, Alpha,摩托罗拉的PowerPC。 具体情形参考处理器手册。

 

一般来说,大部分用户的操作系统(如windows,FreeBsd,Linux)是LittleEndian的。少部分,如MACOS ,是BigEndian 的。所以说,LittleEndian还是BigEndian与操作系统和芯片类型都有关系。

 

举例:0x1122,使用LittleEndian方式时,低字节存储0x22,高字节存储0x11

而使用BigEndian方式时,低字节存储0x11,高字节存储0x22

 

【用函数判断系统是BigEndian还是LittleEndian】

bool IsBig_Endian()

//如果字节序为big-endian,返回true;

//反之为   little-endian,返回false

{

    unsigned shorttest = 0x1122;

    if(*( (unsignedchar*) &test ) == 0x11)

       return TRUE;

else

    return FALSE;

 

}//IsBig_Endian()

 

 

补码

 

——负数的保存形式快速转换方式:

 

-5的存储的十六进制数(补码)的快速转化方式:

 

e.g.INT16S存储,65536-5=65531,即0xFFFB,i.e.0xFFFBis -5的补码;

 

同理,INT8S的-16的补码为256-16=240,即0xF0;

 

同理,已知0xFFF0为INT16S的补码,对应的十进制数为-16(0xFFF0-65536)

 

 

 

数值0的补码只有一个,即      [0]补=00000000B。

 

负零,即0x1000000(if8-bit),表示-128(ifunsigned char)

 

浮点数的存储格式

浮点数的存储格式是符号+阶码(定点整数)+尾数(定点小数)

SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM

即1位符号位(0为正,1为负),8位指数位,23位尾数位

浮点数存储前先转化成2的k次方形式,即:

f = A1*2^k + A2*2^(k-1) + ... + Ak +... +An*2^(-m) (Ai = {0,1}, A1 = 1)

如5.5=2^2+ 2^0 + 2^(-1)

其中的k就是指数,加127后组成8位指数位

5.5的指数位就是2+127= 129 = 10000001

A2A3.....An就是尾数位,不足23位后补0

所以5.5= 01000000101000000000000000000000 = 40A00000

所以,对浮点数*2、/2只要对8位符号位+、- 即可,但不是左移、右移

内存分配malloc,calloc,realloc

void* realloc(void* ptr, unsigned newsize);

void* malloc(unsigned size);

void* calloc(size_t nelem, size_t elsize);都在stdlib.h函数库内。

       malloc与calloc的区别为1块与n块的区别:malloc调用形式为(类型*)malloc(size):在内存的动态存储区中分配一块长度为"size"字节的连续区域,返回该区域的首地址。

       calloc调用形式为(类型*)calloc(n,size):在内存的动态存储区中分配n块长度为"size"字节的连续区域,返回首地址。

       realloc 不能保证重新分配后的内存空间和原来的内存空间指在同一内存地址,它返回的指针很可能指向一个新的地址。所以,在代码中,必须把realloc返回的值,重新赋给p 如:

  p= (char *) realloc (p, old_size + new_size);

甚至,你可以传一个空指针(0)给realloc ,则此时realloc作用完全相当于malloc。如:

int* p = (char *) realloc (0,old_size + new_size); //全新分配一个内存空间,作用完全等同于以下这行: int*p = (char *) malloc(old_size + new_size);

 

calloc相比malloc会清零。(linux调用malloc实际上是calloc)

realloc: 重新分配内存,realloc新开辟的内存首地址可能同上一次的不一样,

而且新增加的内存空间不会清零(N>M)

        e.g. intptr =(int *)malloc(M);

intptr = (int *)realloc(intptr, N);

 

Conclusion:

•     始终结合使用 memset 和 malloc,或始终使用 calloc。

•     每当向指针写入值时,都要确保对可用字节数和所写入的字节数进行交叉核对。

•     在对指针赋值前,要确保没有内存位置会变为孤立的。

•     每当释放结构化的元素(而该元素又包含指向动态分配的内存位置的指针)时,都应首先遍历子内存位置并从那里开始释放,然后再遍历回父节点。

•     始终正确处理返回动态分配的内存引用的函数返回值。

•     每个 malloc 都要有一个对应的 free。

•     确保您不是在访问空指针。

 

extern “C”

extern “C“就是告诉C++编译器,到了这里要用C编译器的方式来编译,即extern"C"是连接申明(linkagedeclaration),被extern"C"修饰的变量和函数是按照C语言方式编译和连接的。从而实现C++与C及其它语言的混合编程。

 

例如:变量a在定义和声明的写法分别如下:

 

在cpp定义变量时,这样定义:

extern "C" {

  int a;

};

 

在*.h中声明如下

#ifdef _cplusplus

extern "C" {

#endif

extern int a;

#ifdef _cplusplus

};

#endif

 

在C文件中包含*.h,并使用变量a

 

字节序

小尾(LittleEndian)就是低位字节排放在内存的低端,即先存放低字节。例如对于一个4字节的整数Byte3Byte2 Byte1 Byte0将在内存中按照如下顺序排放:

Base Address+0   Byte0

Base Address+1   Byte1

Base Address+2   Byte2

Base Address+3   Byte3

Intel处理器大多数使用小尾(LittleEndian)字节序。

 

大尾(BigEndian)就是高位字节排放在内存的低端。

Motorola处理器大多数使用大尾(BigEndian)字节序。

网络字节序:TCP/IP各层协议将字节序定义为大尾,因此TCP/IP协议中使用的字节序通常称之为网络字节序。

字节对齐

        所谓对齐,即数据边界对齐,就是地址必须能整除一个整数,这个就是对齐参数(alignmentvalue),也叫做偏移量。合法的取值范围是2的几次幂1、2、4、6、16….         

   主要针对结构体中各个成员的起始地址(对齐)以及整个结构体的占用字节(填充字节)                                                                                                                                                                                                                                                                                                                                                        

        字节对齐操作可以解决以下两个主要的问题:                                                                                                                                                                                                                                               

        1.访存效率问题(便于一次读取数据);2.强制类型转换问题。                                                                                                                            

                                                                                                                                                                                                                                                                                                                                                 

        #pragma pack( n)                                                                                                                                                                                                                                                                                                         

一般用法如下:(一字节对齐)

#pragma pack(1)

struct sample {

        .......

};

#pragma pack()

        “结构体中的数据成员,除了第一个是始终放在最开始的地方,其它数据成员的地址必须是它本身大小或对齐参数两者中较小的一个的倍数。”                      

        “结构体最后的大小,要么是pack的倍数,要么是最大成员自身所占字节数的倍数,取较小的”                                                                                                                

                                                                                                                                                                                                                                                                                                                                                 

        __declspec(align(n) )                                                                                                                                                                                                                                                                                    

        当数据定义中出现__declspec(align() )时,指定类型的对齐长度还要用自身长度和这里指定的数值比较,然后取其中较大的。                                               

        特别注意:修饰结构体时,只是对结构体的对齐进行限制,对其成员没有效力,见下面的例子                                                                                                                         

                                                                                                                                                                                                                                                                                                                                                 

        当一个变量或结构体同时受__declspec(align(#) )和#pragmapack( n )影响时,前者的优先级高。                                                                                           

        (1)成员的地址决定于前者及后者,其要么是前者的倍数,要么是后者的倍数,要么是成员的大小的倍数,取最小。                                                                       

        (2)结构体最后的大小于前者有关,其要么是前者的倍数,要么是结构体中最大偏移量的倍数,取最大。                                                                                             

        另外,align只是影响其修饰的类型,不像pack影响一段代码,so,当align修饰结构体时,结构体内部的成员的对齐不受align影响,但对于pack会影响到stuct的成员

                                                                                                                                                                                                                                                                                                                                                 

        应用1 为了避免容易产生的误解,设置DUM/padding来补齐字节空档                                                                                                                                                                                                  

        应用2 改变成员顺序达到节约内存的目的                                                                                                                                                                                                                                         

        For example                                                                                                                                                                                                                                                                                                    

        #pragma pack( n)                            struct A{                                                                                                                                                                                                                                                              

        struct B                                            char a;                                                                                                                                                                                                                      

        {                                                                        short b;                                                                                                                                                                                                                    

           …                                                      };                                                                                                                                                                                                                                                                          

           A m_a;                                                                                                                                                                                                                                                                                                                         

           …                                                                                                                                                                                                                                                                                                                                   

        }                                                                                                                                                                                                                                                                                                                                        

        则这个m_a对齐参数是A中最大的数据类型的大小和n中较小者。                                                                                                                                                                                       

        For example                                                                                                                                                                                                                                                                                                    

        #include"StdAfx.h"                                                                                                                                                                                                                                                                                       

        #include<string.h>                                                                                                                                                                                                                                                                                        

        #include<stdio.h>                                                                                                                                                                                                                                                                                         

        #include<iostream>                                                                                                                                                                                                                                                                                     

                                                                                                                                                                                                                                                                                                                                                 

        using   namespace  std;                                                                                                                                                                                                                                                                               

                                                                                                                                                                                                                                                                                                                                                 

        __declspec(align(16) )struct D                                                                                                                                                                                                                                                    

        // cdecl是申明函数使用c样式.declspec是微软的编译指示符,declare   special的意思.                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        {                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

          int i1;   4                                                                                                                                                                                                                                                                                                         

                                      4                                                                                                                                                                                                                                                                                                         

          double d1;         8                                                                                                                                                                                                                                                                                                         

                                                                                                                                                                                                                                                                                                                                                 

          int i2;   4                                                                                                                                                                                                                                                                                                         

                                                                                                                                                                                                                                                                                                                                                 

          int i3;   4                                                                                                                                                                                                                                                                                                         

                                      8                                                                                                                                                                                                                                                                                                         

        };                           32                                                                                                                                                                                                                                                                                                       

                                                                                                                                                                                                                                                                                                                                                 

        __declspec(align(64) ) struct E                                                                                                                                                                                                                                                    

                                                                                                                                                                                                                                                                                                                                                 

        {                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

          int i1;   4                                                                                                                                                                                                                                                                                                         

                                      12                                                                                                                                                                                                                                                                                                       

          D m_d;               32                                                                                                                                                                                                                                                                                                       

                                                                                                                                                                                                                                                                                                                                                 

          int i2;   4                                                                                                                                                                                                                                                                                                         

                                      12                                                                                                                                                                                                                                                                                                       

        };                           64                                                                                                                                                                                                                                                                                                       

                                                                                                                                                                                                                                                                                                                                                 

                                                                                                                                                                                                                                                                                                                                                 

        int main(intargc, int* argv[])                                                                                                                                                                                                                                                       

                                                                                                                                                                                                                                                                                                                                                 

        {                                                                                                                                                                                                                                                                                                                                        

          struct E e;                                                                                                                                                                                                                                                                                                      

                                                                                                                                                                                                                                                                                                                                                 

          cout<<sizeof(D) <<endl;                                                                                                                                                                                                                                                                             

          cout<<sizeof(E) <<endl;                                                                                                                                                                                                                                                                             

          cout<<&e.i1<<endl;                                                                                                                                                                                                                                                                                    

          cout<<&e.m_d.i1<<endl;                                                                                                                                                                                                                                                                           

          cout<<&e.m_d.d1<<endl;                                                                                                                                                                                                                                                                          

          cout<<&e.m_d.i2<<endl;                                                                                                                                                                                                                                                                           

          cout<<&e.m_d.i3<<endl;                                                                                                                                                                                                                                                                           

          cout<<&e.i2<<endl;                                                                                                                                                                                                                                                                                    

                                                                                                                                                                                                                                                                                                                                                 

                                                                                                                                                                                                                                                                                                                                                 

          return 0;                                                                                                                                                                                                                                                                                                                       

        }                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        Result:                                                                                                                                                                                                                                                                                                              

        32                                                                                                                                                                                                                                                                                                                                     

        64                                                                                                                                                                                                                                                                                                                                     

        0012FEC0                                                                                                                                                                                                                                                                                                                       

        0012FED0                                                                                                                                                                                                                                                                                                                       

        0012FED8                                                                                                                                                                                                                                                                                                                       

        0012FEE0                                                                                                                                                                                                                                                                                                                       

        0012FEE4                                                                                                                                                                                                                                                                                                                       

        0012FEF0                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        For example 3                                                                                                                                                                                                                                                                                                

        #include"StdAfx.h"                                                                                                                                                                                                                                                                                       

        #include<string.h>                                                                                                                                                                                                                                                                                        

        #include<stdio.h>                                                                                                                                                                                                                                                                                         

        #include<iostream>                                                                                                                                                                                                                                                                                     

                                                                                                                                                                                                                                                                                                                                                 

        using   namespace  std;                                                                                                                                                                                                                                                                               

                                                                                                                                                                                                                                                                                                                                                 

        __declspec(align(16) )struct D                                                                                                                                                                                                                                                    

                                                                                                                                                                                                                                                                                                                                                 

        {                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

          int i1;   4                                                                                                                                                                                                                                                                                                         

                                      4                                                                                                                                                                                                                                                                                                         

          double d1;         8                                                                                                                                                                                                                                                                                                         

                                                                                                                                                                                                                                                                                                                                                 

          int i2;   4                                                                                                                                                                                                                                                                                                         

                                                                                                                                                                                                                                                                                                                                                 

          int i3;   4                                                                                                                                                                                                                                                                                                         

                                      8                                                                                                                                                                                                                                                                                                         

        };                           32                                                                                                                                                                                                                                                                                                       

                                                                                                                                                                                                                                                                                                                                                 

         #pragma pack(1)                                                                                                                                                                                                                                                                                                          

        struct E                                                                                                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                                                                                                                 

        {                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

          int i1;   4                            0012FF30                                                                                                                                                                                                                                                            

          char c1;              1                            0012FF34                                                                                                                                                                                                                                                            

                                      11                                                                                                                                                                                                                                                                                                       

          D m_d;               32                          0012FF40             align 优先级大于 pack!                                                                                                                                                                                  

          char c2;              1                            0012FF60                                                                                                                                                                                                                                                            

          int i2;   4                            0012FF61                                                                                                                                                                                                                                                            

                                      11                                                        结构体的对齐位置也受到align的影响                                                                                                                                                      

        };                           64                                                                                                                                                                                                                                                                                                       

        #pragma pack()                                                                                                                                                                                                                                                                                              

                                                                                                                                                                                                                                                                                                                                                 

        int main(intargc, int* argv[])                                                                                                                                                                                                                                                       

                                                                                                                                                                                                                                                                                                                                                 

        {                                                                                                                                                                                                                                                                                                                                        

          struct E e;                                                                                                                                                                                                                                                                                                      

          void * c1=(void*)&e.c1;                                                                                                                                                                                                                                                                             

          void * c2=(void*)&e.c2;                                                                                                                                                                                                                                                                             

                                                                                                                                                                                                                                                                                                                                                 

          cout<<sizeof(D) <<endl;                                                                                                                                                                                                                                                                             

          cout<<sizeof(E) <<endl;                                                                                                                                                                                                                                                                             

          cout<<&e.i1<<endl;                                                                                                                                                                                                                                                                                    

          cout<<c1<<endl;                                                                                                                                                                                                                                                                                                         

          cout<<&e.m_d.i1<<endl;                                                                                                                                                                                                                                                                           

          cout<<&e.m_d.d1<<endl;                                                                                                                                                                                                                                                                          

          cout<<&e.m_d.i2<<endl;                                                                                                                                                                                                                                                                           

          cout<<&e.m_d.i3<<endl;                                                                                                                                                                                                                                                                           

          cout<<c2<<endl;                                                                                                                                                                                                                                                                                                         

          cout<<&e.i2<<endl;                                                                                                                                                                                                                                                                                    

                                                                                                                                                                                                                                                                                                                                                 

                                                                                                                                                                                                                                                                                                                                                 

          return 0;                                                                                                                                                                                                                                                                                                                       

        }                                                                                                                                                                                                                                                                                                                                        

        Result:                                                                                                                                                                                                                                                                                                                         

        32                                                                                                                                                                                                                                                                                                                                     

        64                                                                                                                                                                                                                                                                                                                                     

        0012FF30                                                                                                                                                                                                                                                                                                                        

        0012FF34                                                                                                                                                                                                                                                                                                                        

        0012FF40                                                                                                                                                                                                                                                                                                                        

        0012FF48                                                                                                                                                                                                                                                                                                                        

        0012FF50                                                                                                                                                                                                                                                                                                                        

        0012FF54                                                                                                                                                                                                                                                                                                                        

        0012FF60                                                                                                                                                                                                                                                                                                                        

        0012FF61                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        特殊情况:structE中的成员m_d被align修饰(优先级大于pack),所以structE按照16字节对齐,sosizeof(E)等于64。                                                                                

反码 补码                                                                                  

对于有符号变量来说:                                                    

我们都知道计算机中的数据是用 补码 表示的。相信大家对他们的概念都比较熟悉了,现在说一下需要注意的几个地方。 我们暂且用8 位表示。

 1、原码的表示范围是 -127 ~ +127 共256个。(包含一个+0 和-0)。正是由于原码有 正负零之分,给我们的运算带来了很大的麻烦。所以才引进 反码。

                                                                                  

 2、反码的表示范围是 -127 ~ +127 共256个。(包含一个+0 和-0)。

    正数的反码与原码相同。负数的反码,首位(符号位)不变,其他位取反。

   例: +0 反码是:00000000                                          

       -0 反码是:11111111(符号位是1,其他位取反)

                                                                                  

 3、补码的表示范围是 -128 ~ +127 共256个。       

   例:+0 的补码:00000000                                           

       -0 的补码:00000000(反码 加1)

                                                                                  

      例: -127 的补码 怎么计算呢?               

         -127 原码是11111111 ---> 反码为10000000 ---->补码为10000001 。即 在计算机中,10000001 就表示-127。

                                                                                  

 4、在这 8 位系统中,-128 没有相对应的原码和反码,它在计算机里面的表示形式是:10000000

   所以,计算机为32位的时候,10000000000000000000000000000000表示-2(31)。2的 31 次方。

                                                                                  

 5、对于编程语言中的 移位 运算,比如一个32位的int 型左移33 位,这样的话我们可以取模运算。

即 对于n>32的数,语言规定的就是 实际移位数为(n-32)。比如左移 33位,实际上和左移1 位 是相同的。

                                                                                  

函数指针数组的用法实例

/*  FunctionPointer  */

typedef     void    (*pFunc)( void );

 

/*  FunctionTable  */

static const pEvProcFunc nPowTiProcFuncTbl[] = {

   nvdPowTiProcPowOn            ,  /*00*/

   nvdPowTiProcPowOff            ,/*01*/     

};

 

static VOID nvdPowTiProcPowOn( VOID )

{

        ……

}

 

static VOID nvdPowTiProcPowOff( VOID )

{

        ……..

}

3种字符类型               

ANSI C 提供了3种字符类型,分别是char、signedchar、unsignedchar。。

Other:char相当于signedchar或者unsignedchar,但是这取决于编译器。

这三种字符类型都是按照1个字节存储的,可以保存256个不同的值。

signedchar取值范围是-128 到127

unsigned char 取值范围是 0 到 255

                                                                                                                                                                                                                                                                                                    

指针和数组                                                      

                                                                                                                                                                                                                                                                                                                                                 

        (1)指针和数组名的差别                                                                                                                                                                                                                                                                                     

        char str[20], *ptr;  ptr=str;                                                                                                                                                                                                                                                  

        ptr和str都可以用下标或者指针来访问;但是str是常量,不能被修改,如str++就是非法的                                                                                                                             

        (2)多维数组的指针运用                                                                                                                                                                                                                                                                                     

        在一个三维数组中,引用元素c[i][j][k]的地址计算最终将换成:*(*(*(c+i)+j)+k)。                                                                                                                                      

        若有如下说明:                                                                                                                                                                                                                                                                                                          

          inta[3][4];                                                                                                                                                                                                                                                                                             

          int *p;                                                                                                                                                                                                                                                                                                   

          p=a;                                                                                                                                                                                                                                                                                                                        

          p是指向整型变量的指针;p=a使p指向整型二维数组a的首地址。                                                                                                                                                                             

        *(*(a+1)+2)表示取a[1][2]的内容;                                                                                                                                                                                                                                               

        *(*(p+1)+2)是不对的,p的偏移量根据指针类型来定,p+1指向a[0][1],nota[1][0];                                                                                                                                      

        牢记:指针加减运算的字节数是他指向的数据类型所占空间(函数名也不例外)                                                                                                                                                             

                                                                                                                                                                                                                                                                                                                                                 

        函数指针数组的使用                                                                                                                                                                                                                                                                                              

        例子:                                                                                                                                                                                                                                                                                                                            

        /*  Event Process Function Pointer  */                                                                                                                                                                                                                                       

        typedef     void   (*pEvProcFunc)( void );                                                                                                                                                                                                                    

                                                                                                                                                                                                                                                                                                                                                 

        /*  TimeOut Process Function Table  */                                                                                                                                                                                                                                     

        static constpEvProcFunc nPowTiProcFuncTbl[] = {                                                                                                                                                                                                                

            nvdPowTiProcPowOn             , /*00*/                                                                                                                                                                                                                    

            nvdPowTiProcPowOff            , /*01*/                                                                                                                                                                                                                     

           nvdPowTiProcStbyOut          ,/*02*/                                                                                                                                                                                                                       

            nvdPowTiProcStbyIn           ,/*03*/                                                                                                                                                                                                           

        };                                                                                                                                                                                                                                                                                                                                      

                                                                                                                                                                                                                                        

sizeof和strlen的区别

sizeof是运算符,strlen是函数

sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以\"\0\"结尾的。

    charstr[20]=\"0123456789″;   

    int a=strlen(str);//a=10;   

    int b=sizeof(str); //而b=20;

strlen的结果要在运行的时候才能计算出来,时用来计算字符串的长度,不是类型占内存的大小。   

sizeof后如果是类型必须加括弧,如果是变量名可以不加括弧。这是因为sizeof是个操作符不是个函数。

 

当适用了于一个结构类型时或变量,sizeof 返回实际的大小, 当适用一静态地空间数组,sizeof 归还全部数组的尺寸。sizeof 操作符不能返回动态地被分派了的数组或外部的数组的尺寸。

 

    数组作为参数传给函数时传的是指针而不是数组,传递的是数组的首地址,如:

   

    fun(char[8])

   

    fun(char [])

   

    都等价于 fun(char *)

 

 

 

    char* s =\"0123456789″;

   

    sizeof(s) 结果4  s是指向字符串常量的字符指针

   

    sizeof(*s) 结果1 *s是第一个字符

   

    char s[] =\"0123456789″;

   

    sizeof(s) 结果11  s是数组,计算到\0位置,因此是10+1

   

    sizeof(*s) 结果1 *s是第一个字符

   

    char s[100] =\"0123456789″;

   

    sizeof(s) 结果是100s表示在内存中的大小100×1

   

    strlen(s) 结果是10  strlen是个函数内部实现是用一个循环计算到\0为止之前

   

    int s[100] =\"0123456789″;

   

    sizeof(s) 结果400  s表示再内存中的大小 100×4

   

    strlen(s) 错误strlen的参数只能是char*且必须是以\"\0\"结尾的

文件操作

        Ansi C对文件的操作

-> 利用FILE结构处理字节流文件                                                                                                                                                                                                                                    

        FILE *pFile =fopen("filename.txt","w");                                                                                                                                                                                                                                   

                                                                                                                                                                                                                                                                                                                                                 

        fclose 关闭:将文件内存缓冲区立即写入磁盘文件中                                                                                                                                                                                                                    

        flush 刷新:将文件内存缓冲区立即写入磁盘文件中                                                                                                                                                                                                                      

        fseek ftell                                                                                                                                                                                                                                                                                                                       

        fread     fwrite                                                                                                                                                                                                                                                                                                

        fgets                                                                                                                                                                                                                                                                                                                                

                                                                                                                                                                                                                                                                                                                                                 

        FILE*pFile=NULL;                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                           

        if(pFile=fopen("config\\CalibrationSetting.cfg","r"))                                                                                                                                                                                               

        {                                                                                                                                                                                                                                                                                                                                     

                    char strLine[128]={0}; //128 chars isbig enough.                                                                                                                                                                                      

                    char * pf=NULL, *pStop=NULL;                                                                                                                                                                                                                                               

                    do                                                                                                                                                                                                                                                                                                                  

                    {                                                                                                                                                                                                                                                                                                                      

                                   pf = fgets(strLine,128, pFile);                                                                                                                                                                                                                     

                                   if(strstr(strLine,"ALL bands of GSM Calibration Enable/Disable"))                                                                                                                       

                                   //注意,用fgets时strLine最后是10(换行符),所以不能用strcmp                                                                                                                                     

                                   {                                                                                                                                                                                                                                                                                                       

                                                  if( 0== strtol(fgets(strLine, 2, pFile), &pStop, 10) )                                                                                                                                                      

                                                  {                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                           

                                                  }                                                                                                                                                                                                                                                                                        

                                   }                                                                                                                                                                                                                                                                                                       

                    }while(pf)                                                                                                                                                                                                                                                                                                      

        fclose(pFile);                                                                                                                                                                                                                                                                                                

        }                                                                                                                                                                                                                                                                                                                                     

        else return 0;                             

 

        POSIX文件操作:

 

e.g.  //ubuntu 10.04GCC 4.4.3

#include <sys/types.h>

 

#include <sys/stat.h>

 

#include <sys/fcntl.h>

 

#include <unistd.h>

 

#include <string.h>

 

#include <stdio.h>

 

 

 

int main()

 

{

 

        int fd,readnum, writenum;

 

        char buff[128];

 

 

 

        fd =open("./1.c", O_RDWR);

 

        if (-1 == fd) {

 

                       printf("openfile error!\n");

 

                       return0;

 

        }

 

 

 

        lseek(fd, -128,SEEK_END);

 

        readnum =read(fd, buff, 127);

 

        printf("%dbyte read!\n", readnum);

 

        buff[readnum] ='\0';

 

        printf("%s\n\n",buff);

 

 

 

        lseek(fd, 0,SEEK_SET);

 

        strcpy(buff,"a string write by file!\n");

 

        writenum =write(fd, buff, strlen(buff));

 

        printf("%dbytes write!\n", writenum);

 

 

 

        close (fd);

 

        return 0;

 

}

 

 

ANSI和POSIX文件操作对比

仅仅列出几个函数

ANSI:(带缓冲)fopen,fclose。。。。。

POSIX:(不带缓冲)open,close 。。。。

 

 

                                                                                                                                                                                                                                                                                                                                                 

        也可以用MFC提供的CFILE来进行文件操作                                                                                                                                                                                                                                                    

        另外还可以用CPP中输入输入流来进行文件读写                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                 

        先介绍下cout/cin,externostream cout;extern istream cin;                                                                                                                                                                                            

        “标准输入输出流”对象                                                                                                                                                                                                                                                                                        

        cout是一个iostream类的对象,它有一个成员运算符函数operator<<,每次调用的时候就会向输出设备(一般就是屏幕啦)输出东东。                                        

                                                                                                                                                                                                                                                                                                                                                 

        C++入门解惑——浅析cout                                                                                                                                                                                                                                                                               

        [2005-11-2311:58:02] [来源:网络] [我要投稿]                                                                                                                                                                                                                     

        本文章地址:http://tech.163.com/05/1123/11/2388N2D40009159Q.html[点此复制地址]                                                                                                                                      

                                                                                                                                                                                                                                                                                                                                                 

        #include                                                                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                 

        usingnamespacestd;                                                                                                                                                                                                                                                                                    

                                                                                                                                                                                                                                                                                                                                                 

        intmain()                                                                                                                                                                                                                                                                                                                         

                                                                                                                                                                                                                                                                                                                                                 

        {                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        cout<<"Hello,World!"<                                                                                                                                                                                                                                                                               

                                                                                                                                                                                                                                                                                                                                                 

        return0;                                                                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                 

        }                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        由于以前学过C,所以这段代码的其它部分在我看来都还算“正常”,然而cout却很独特:既不是函数,似乎也不是C++特别规定出来的像if,for一类有特殊语法的“语句”。由于只是初步介绍,所以那本书只是简单的说cout是C++中的“标准输入输出流”对象……这于我而言实在是一个很深奥的术语。这还没完,之后又遇见了cin……因为不知底细,从此使用它们的时候都诚惶诚恐,几欲逃回C时代那简明的printf(),毕竟好歹我可以说:我在调用的是一个函数。那有着一长串<<、>>的玩意,究竟算怎么回事呢?我一直想把它们当作关键字,可偏偏不是,而且居然是用C++语言“做”出来的,呵!但printf()用多了就开始有人好心地批判我的程序“C语言痕迹过重”……

                                                                                                                                                                                                                                                                                                                                                 

        后来随着学习的深入,总算大概明白了cout/cin/cerr/...的鬼把戏:那些东东不过是变着法儿“哄人”,其实说到底还是函数调用,不过这函数有些特殊,用的是运算符重载,确切地说(以下还是以cout为例)是重载了“<<”运算符。我们现在就让它现出函数的本来面目,请看HelloWorld!的等效版本:

                                                                                                                                                                                                                                                                                                                                                 

        #include                                                                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                 

        usingnamespacestd;                                                                                                                                                                                                                                                                                    

                                                                                                                                                                                                                                                                                                                                                 

        intmain()                                                                                                                                                                                                                                                                                                                         

                                                                                                                                                                                                                                                                                                                                                 

        {                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        cout.operator<<("Hello,World!");                                                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                                                                                                                 

        cout.operator<<(endl);                                                                                                                                                                                                                                                                               

                                                                                                                                                                                                                                                                                                                                                 

        return0;                                                                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                 

        }                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        编译运行,结果与经典版无二。上面程序应该更容易理解了:cout是一个iostream类的对象,它有一个成员运算符函数operator<<,每次调用的时候就会向输出设备(一般就是屏幕啦)输出东东。嗯,这里有一个问题:为什么函数operator<<能够接受不同类型的数据,如整型、浮点型、字符串甚至指针,等等呢?

                                                                                                                                                                                                                                                                                                                                                 

        我想你现在已经猜到了,没错,就是用运算符重载。运算符函数与一般函数基本无异,可以任意重载。标准库的设计者们早已经为我们定制了iostream::operator<<对于各种C++基本数据类型的重载版本,这才使得我们这些初学者们一上来就享受到cout<<"Hello,World!"<

                                                                                                                                                                                                                                                                                                                                                 

        cout.operator<<("Hello,World!").operator<<(endl);                                                                                                                                                                                                             

                                                                                                                                                                                                                                                                                                                                                 

        才算“强等效”。究竟可不可以这样写?向编译器确认一下……OK,NoProblem!                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                 

        嗯,我们已经基本上看出了cout的实质,现在不妨动动手,自己来实现一个cout的简化版(Lite),为了区分,我们把我们设计的cout对象命名的myout,myout对象所属的类为MyOutstream。我们要做的就是为MyOutstream类重载一系列不同类型的operator<<运算符函数,简单起见,这里我们仅实现了对整型(int)与字符串型(char*)的重载。为了表示与iostream断绝关系,我们不再用头文件iostream,而使用古老的stdio中的printf函数进行输出,程序很简单,包括完整的main函数,均列如下:

                                                                                                                                                                                                                                                                                                                                                 

        #include//在C和一些古老的C++中是stdio.h,新标准为了使标准库                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        //的头文件与用户头文件区别开,均推荐使用不用扩展名                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                 

        //的版本,对于原有C库,不用扩展名时头文件名前面要加c                                                                                                                                                                                                                 

                                                                                                                                                                                                                                                                                                                                                 

        classMyOutstream                                                                                                                                                                                                                                                                                                      

                                                                                                                                                                                                                                                                                                                                                 

        {                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        public:                                                                                                                                                                                                                                                                                                              

                                                                                                                                                                                                                                                                                                                                                 

        constMyOutstream&operator<<(intvalue)const;//对整型变量的重载                                                                                                                                                                           

                                                                                                                                                                                                                                                                                                                                                 

        constMyOutstream&operator<<(char*str)const;//对字符串型的重载                                                                                                                                                                           

                                                                                                                                                                                                                                                                                                                                                 

        };                                                                                                                                                                                                                                                                                                                                      

                                                                                                                                                                                                                                                                                                                                                 

        constMyOutstream&MyOutstream::operator<<(intvalue)const                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        {                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        printf("%d",value);                                                                                                                                                                                                                                                                                       

                                                                                                                                                                                                                                                                                                                                                 

        return*this;//注意这个返回……                                                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                                                                                                                 

        }                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        constMyOutstream&MyOutstream::operator<<(char*str)const                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        {                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        printf("%s",str);                                                                                                                                                                                                                                                                              

                                                                                                                                                                                                                                                                                                                                                 

        return*this;//同样,这里也留意一下……                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                 

        }                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        MyOutstreammyout;//随时随地为我们服务的全局对象myout                                                                                                                                                                                                    

                                                                                                                                                                                                                                                                                                                                                 

        intmain()                                                                                                                                                                                                                                                                                                                         

                                                                                                                                                                                                                                                                                                                                                 

        {                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        inta=2003;                                                                                                                                                                                                                                                                                                                      

                                                                                                                                                                                                                                                                                                                                                 

        char*myStr="Hello,World!";                                                                                                                                                                                                                                                                      

                                                                                                                                                                                                                                                                                                                                                 

        myout<                                                                                                                                                                                                                                                                                                                           

                                                                                                                                                                                                                                                                                                                                                 

        return0;                                                                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                 

        }                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        我们已经的myout已经初具形态,可以为我们工作了。程序中的注释指出两处要我们特别注意的:即是operator<<函数执行完毕之后,总是返回一个它本身的引用,输出已经完成,为何还要多此一举?

                                                                                                                                                                                                                                                                                                                                                 

        还记得那个有点奇异的cout.operator<<("Hello,World!").operator<<(endl)么?它能实现意味着我们可以连着书写                                                                         

                                                                                                                                                                                                                                                                                                                                                 

        cout<<"Hello,World!"<                                                                                                                                                                                                                                                                               

                                                                                                                                                                                                                                                                                                                                                 

        而不是                                                                                                                                                                                                                                                                                                             

                                                                                                                                                                                                                                                                                                                                                 

        cout<<"Hello,World!";                                                                                                                                                                                                                                                                                

                                                                                                                                                                                                                                                                                                                                                 

        cout<                                                                                                                                                                                                                                                                                                                

                                                                                                                                                                                                                                                                                                                                                 

        为何它可以这样连起来写?我们分析一下:按执行顺序,系统首先调用cout.operator<<("Hello,World!"),然后呢?然后cout.operator<<会返回它本身,就是说在函数的最后一行会出现类似于return*this这样的语句,因此cout.operator<<("Hello,World!")的调用结果就返回了cout,接着它后面又紧跟着.operator<<(endl),这相当于cout.operator<<(endl)——于是又会进行下一个输出,如果往下还有很多<<算符,调用就会一直进行……哇噢,是不是很聪明?现在你明白我们的MyOutstream::operator<<最后一行的奥妙了吧!

                                                                                                                                                                                                                                                                                                                                                 

        再注意一下main函数中最激动人心的那一行:                                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                                                                                                                 

        myout<                                                                                                                                                                                                                                                                                                                           

                                                                                                                                                                                                                                                                                                                                                 

        我们知道,最后出现的"\n"可以实现一个换行,不过我们在用C++时教程中总是有意无意地让我们使用endl,两者看上去似乎一样——究竟其中有什么玄妙?查书,书上说endl是一个操纵符(manipulator),它不但实现了换行操作,而且还对输出缓冲区进行刷新。什么意思呢?原来在执行输出操作之后,数据并非立刻传到输出设备,而是先进入一个缓冲区,当适宜的时机(如设备空闲)后再由缓冲区传入,也可以通过操纵符flush进行强制刷新:

                                                                                                                                                                                                                                                                                                                                                 

        cout<<"Hello,World!"<<"Flushthescreennow!!!"<                                                                                                                                                                                                                               

                                                                                                                                                                                                                                                                                                                                                 

        这样当程序执行到operator<<(flash)之前,有可能前面的字符串数据还在缓冲区中而不是显示在屏幕上,但执行operator<<(flash)之后,程序会强制把缓冲区的数据全部搬运到输出设备并将其清空。而操纵符endl相当于<<"\n"<

                                                                                                                                                                                                                                                                                                                                                 

        不过可能在屏幕上显示是手动刷新与否区别看来都不大。但对于文件等输出对象就不大一样了:过于频繁的刷新意味着老是写盘,会影响速度。因此通常是写入一定的字节数后再刷新,如何操作?靠的就是这些操纵符。

                                                                                                                                                                                                                                                                                                                                                 

        好了,说了这么多,C++的iostream家族与C的print/scanf家庭相比究竟有何优势?首先是类型处理更安全、智能,想想printf中对付int、float等的"%d"、"%f"等说明符真是多余且麻烦,万一用错了搞不好还会死掉;其次是扩展性更强:我要是新定义一个复数类Complex,printf对其是无能为力,最多只能分别输出实、虚部,而iostream使用的<<、>>操作符都是可重载的,你只要重载相关的运算符就可以了;而且流风格的写法也比较自然简洁,不是么?

                                                                                                                                                                                                                                                                                                                                                 

                                                                                                                                                                                                                                                                                                                                                 

        typedefbasic_istream<char, char_traits<char> > istream;                                                                                                                                                                                    

        typedefbasic_ostream<char, char_traits<char> > ostream;                                                                                                                                                                                                

        typedefbasic_iostream<char, char_traits<char> > iostream;                                                                                                                                                                               

                                                                                                                                                                                                                                                                                                                                                 

        basic_iostream                                                                                                                                                                                                                                                                                              

        template<class E, class T = char_traits<E> >                                                                                                                                                                                                                           

            class basic_iostream : publicbasic_istream<E, T>,                                                                                                                                                                                              

                public basic_ostream<E, T> {                                                                                                                                                                                                                                              

        public:                                                                                                                                                                                                                                                                                                              

            explicitbasic_iostream(basic_streambuf<E, T> *sb);                                                                                                                                                                                          

            virtual ~basic_iostream();                                                                                                                                                                                                                                                         

            };                                                                                                                                                                                                                                                                                                                   

                                                                                                                                                                                                                                                                                                                                                 

                                                                                                                                                                                                                                                                                                                                                 

        写文件操作                                                                                                                                                                                                                                                                                                                   

        ofstream fout;                                                                                                                                                                                                                                                                                               

        fout.open("code.txt");                                                                                                                                                                                                                                                                                 

        fout <<flush;                                                                                                                                                                                                                                                                                                  

        fout.close();                                                                                                                                                                                                                                                                                                    

        读文件操作                                                                                                                                                                                                                                                                                                                   

        ifstreamfin("log.txt");                                                                                                                                                                                                                                                                   

        fin.getline(acStrLine,COLUMN_NUM_MAX);                                                                                                                                                                                                                                         

                                                                                                                                                                                                                                                                                                                                                 

        rdbuf来重定向流                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        Example:                                                                                                                                                                                                                                                                                  

        // 重定向日志输出                                                                                                                                                                                                                                                                                                  

        ofstreamfile((LOG_PATH + "collect/" + fileName + ".log").c_str());                                                                                                                                                                     

        streambuf*buffer = cout.rdbuf(); //oldbuffer,STDOUT的缓冲区                                                                                                                                                                        

        cout.rdbuf(file.rdbuf());//cout 重定向到file输出流                                                                                                                                                                                                         

                                                                                                                                                                                                                                                                                                                                           

        // 恢复输出的重定向                                                                                                                                                                                                                                                                               

        cout.rdbuf(buffer);//重新载入STDOUT的缓冲区                                                                                                                                                                                                             

                                                                                                                                                                                                                                                                                                                                                 

        关于streambuf*rdbuf ( ) const;streambuf* rdbuf ( streambuf* sb )函数的解释如下:                                                                                                                              

        The firstsyntax returns the stream buffer object associated with the stream.                                                                                                                                  

        The secondsyntax associates the stream with sb and returns the stream buffer objectpreviously associated with the stream. In this case, the buffer's control stateis set to goodbit as if a call to member clear().

                                                                                                                                                                                                                                                                                                                                                 

        rdbuf函数有两种调用方法                                                                                                                                                                                                                                                                                      

        basic_streambuf<Elem,Traits> *rdbuf( ) const;                                                                                                                                                                                                                      

        basic_streambuf<Elem,Traits> *rdbuf( basic_streambuf<E, T> *_Sb);                                                                                                                                                               

        1)无参数。返回调用者的流缓冲指针。                                                                                                                                                                                                                                                          

        2)参数为流缓冲指针。它使调用者与参数(流缓冲指针)关联,返回自己当前关联的流缓冲区指针。                                                                                                                

                                                                                                                                                                                                                                                                                                                                                 

                                                                                                                                                                                                                                                                                                                                                 

        Anotherexample:                                                                                                                                                                                                                                                      

   另外在CSDN上面以为老兄的帖子中,还绝伦一个例子,并提出了两个需要注意的地方,我感觉比较重要,就贴过来了。                                                                         

                                                                                                                                                                                                                                                                                                                                                

                                                                                                                                                                                                                                                                                                                                                

        #include                                                                                                                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                                                                                                                

        #include                                                                                                                                                                                                                                                                                                                            

                                                                                                                                                                                                                                                                                                                                                

        int main()                                                                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                

        {                                                                                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                

            std::ofstream log("foo.log");                                                                                                                                                                                                                                                     

                                                                                                                                                                                                                                                                                                                                                

            std::streambuf *oldbuf =std::cout.rdbuf(log.rdbuf());                                                                                                                                                                           

                                                                                                                                                                                                                                                                                                                                                

            std::cout << "输出到标准输出,但实际输出到了foo.log文件中\n";                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                

        log <<"输出到文件,虽然将cout重定向到了log,但不影响log本身的使用\n";                                                                                                                                                                  

                                                                                                                                                                                                                                                                                                                                                

              // 恢复流缓冲区                                                                                                                                                                                                                                                                                       

                                                                                                                                                                                                                                                                                                                                                

            std::cout.rdbuf(oldbuf);                                                                                                                                                                                                                                                                             

                                                                                                                                                                                                                                                                                                                                                

        }                                                                                                                                                                                                                                                                                                                                          

                                                                                                                                                                                                                                                                                                                                                

                                                                                                                                                                                                                                                                                                                                                   

                                                                                                                                                                                                                                                                                                                                                

        注意:                                                                                                                                                                                                                                                                                                                              

                                                                                                                                                                                                                                                                                                                                                

        1.cout可以调用rdbuf来替换缓冲区,但log不能通过调用rdbuf来替换缓冲区。因为ofstream的rdbuf并没有同样的功能。                                               

                                                                                                                                                                                                                                                                                                                                                

        2.对流的重定向,只是作用在一个代码块内{},出了这个{},就恢复为原来的了,但是对在这个代码块内调用的函数,重定向也会生效。                      

                                                                                                                                                                                                                                                                                     

                                                                                                                                                                                                                                                                                                                                                 

        The thirdexample                                                                                                                                                                                                                                                                                         

        假如我们用C语言写一个文件复制程序,比如一个mp3文件,我们首先考虑的是C语言的文件输入输出功能,其思路是建一个指定大小缓冲区,我们从源文件中循环读取缓冲区大小的数据,然后写进目的文件。而在C++中,我们抛弃了这种用字符缓冲区的按字节复制的方法,因为这种方法看起来很繁琐,而且效率一点也不高。下面可以对比这两种方法(程序可以直接执行):

                                                                                                                                                                                                                                                                                                                                                 

        C:实现代码                                                                                                                                                                                                                                                                                                                

                                                                                                                                                                                                                                                                                                                                                 

        #include<stdlib.h>                                                                                                                                                                                                                                                                                         

        #include<stdio.h>                                                                                                                                                                                                                                                                                                         

        int main()                                                                                                                                                                                                                                                                                                                        

        {                                                                                                                                                                                                                                                                                                                                        

         char buf[256];                                                                                                                                                                                                                                                                                               

         FILE *pf1, *pf2;                                                                                                                                                                                                                                                                                             

         if((pf1 = fopen("1.mp3","rb")) == NULL)                                                                                                                                                                                                                   

         {                                                                                                                                                                                                                                                                                                                                       

          printf("源文件打开失败\n");                                                                                                                                                                                                                                                                   

          return 0;                                                                                                                                                                                                                                                                                                                       

         }                                                                                                                                                                                                                                                                                                                                       

         if((pf2 =fopen("2.mp3","wb")) == NULL)                                                                                                                                                                                                                                 

         {                                                                                                                                                                                                                                                                                                                                       

          printf("目标文件打开失败\n");                                                                                                                                                                                                                                                

          return 0;                                                                                                                                                                                                                                                                                                                       

         }                                                                                                                                                                                                                                                                                                                                       

         while(fread(buf,1,256,pf1), !feof(pf1))                                                                                                                                                                                                                                     

         {                                                                                                                                                                                                                                                                                                                                       

          fwrite(buf,1,256,pf2);                                                                                                                                                                                                                                                                  

         }                                                                                                                                                                                                                                                                                                                                       

         fclose(pf1);                                                                                                                                                                                                                                                                                                    

         fclose(pf2);                                                                                                                                                                                                                                                                                                    

         return 0;                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        }                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        在C++中的实现代码:                                                                                                                                                                                                                                                                              

                                                                                                                                                                                                                                                                                                                                                 

        #include<fstream>                                                                                                                                                                                                                                                                                                       

        #include<iostream>                                                                                                                                                                                                                                                                                      

        using namespacestd;                                                                                                                                                                                                                                                                                   

        int main()                                                                                                                                                                                                                                                                                                                        

        {                                                                                                                                                                                                                                                                                                                                        

            fstreamfin("1.mp3",ios::in|ios::binary);                                                                                                                                                                                                                               

            if(!fin.is_open())                                                                                                                                                                                                                                                                                         

         {                                                                                                                                                                                                                                                                                                                                       

          cout << "源文件打开失败" << endl;                                                                                                                                                                                                                                                       

          return 0;                                                                                                                                                                                                                                                                                                                       

         }                                                                                                                                                                                                                                                                                                                                       

            fstreamfout("2.mp3",ios::out|ios::binary);                                                                                                                                                                                                          

         if(! fin.is_open())                                                                                                                                                                                                                                                                                           

         {                                                                                                                                                                                                                                                                                                                                       

          cout << "目标文件打开失败!" << endl;                                                                                                                                                                                                                                  

          return 0;                                                                                                                                                                                                                                                                                                                       

         }                                                                                                                                                                                                                                                                                                                                       

            fout<<fin.rdbuf();                                                                                                                                                                                                                                                                                      

            fin.close();                                                                                                                                                                                                                                                                                                   

            fout.close();                                                                                                                                                                                                                                                                                                

            return 0;                                                                                                                                                                                                                                                                                                      

        }                                                                                                                                                                                                                                                                                                                                        

                                                                                                                                                                                                                                                                                                                                                 

        看起来是不是清晰多了呢,这就是C++中的流缓冲的威力了,程序通过把源文件的流重定向到关联到目的文件的流对象,通过fout<<fin.rdbuf();一句代码就完成了在C语言中的循环读写缓冲区的功能,而且C++中使用的是底层的流缓冲,效率更高!

ProgrammingSkills

Good habit

注意宏定义首先把A和B加上括号

常量加入UL:#define SECONDS_PER_YEAR (60 * 60 * 24 * 365)UL                                                                                 

strlen : not include '\0'                                                                                      

strdup = malloc + strcpy;因此strdup返回的指针需要主动去释放(free)

常量默认是int或者double,尽量写明确后缀:13300999UL,9.0f

2的n次幂=1<<N,或者2<<(N-1)      

 

int main(int argc, char* argv[])

argv是char类型的指针数组,每个元素是指向char类型的指针

strcpy是拷贝包含最后/0结束符在内的所有字符

数组名做函数参数:func(int a[])/func(int a[n]) / func(int *a)

 

#define SWEP(A,B) A=(A+B);B=A-B;A=A-B;

#define CLEAR_STR(STR) memset((STR), '\0', sizeof(STR));

 

类似snprintf和strncpy,防止目标内存溢出

 

Template for dynamic memory usage

char * p = NULL;

p = malloc(1);

free(p);

p = NULL;

宏定义

#ifndef WIN32

#endif

 

#if (_MSC_VER < 1300) && defined(__cplusplus)

#endif

 

#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS)

#endif

 

#if !defined( __CLEANUP_SEH ) && !defined(__CLEANUP_CXX ) && !defined( __CLEANUP_C )

#endif

 

#ifdef 即#if defined;#ifndef是if notdefined的缩写

但是#ifdefined使用灵活:eg#if defined FEATURE_APP_SVCPRG || defined FEATURE_INVENTEC_MODIFY

 

例子:

#if defined a

#undef a

#define a 200

#endif

 

 

调试手段

宏定义使用技巧

1.    重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。

   typedef  unsigned char      boolean;     /* Boolean type. */

   typedef  unsigned long      uint32;      /* Unsigned 32 bit */

   typedef  unsigned short     uint16;      /* Unsigned 16 bit */

   typedef  unsigned char      uint8;       /* Unsigned 8  bit */

   typedef  signed long int    int32;      /* Signed 32 bit */

   typedef  signed short       int16;       /* Signed 16 bit */

   typedef  signed char        int8;        /* Signed 8  bit */

2.    得到指定地址上的一个字节或字

   #define  MEM_B(x) (*((uint8*)(x)))

   #define  MEM_W(x) (*((uint16*)(x)))

3.    得到一个field在结构体(struct)中的偏移量

   #defineFPOS(type,field) ((uint32) &((type *)0)->field)

4.    得到一个结构体中field所占用的字节数

   #defineFSIZ(type,field) sizeof(((type *)0)->field)

5.    求最大值和最小值

   #define  MAX(x,y) (((x)>(y))?(x):(y))

   #define  MIN(x,y) (((x)<(y))?(x):(y))

6.    得到一个变量的地址

   #define  B_PTR(var) ((byte *) (void *) &(var))

   #define  W_PTR(var) ((word *) (void *) &(var))

7.    按照LSB格式把两个字节转化为一个Word

   #define  FLIPW(ray) ((((word) (ray)[0]) * 256) +(ray)[1])

8.    按照LSB格式把一个Word转化为两个字节

   #define  FLOPW( ray, val ) \

      (ray)[0] =((val) / 256); \

      (ray)[1] =((val) & 0xFF)

9.    得到一个字的高位和低位字节

   #define  WORD_LO(***) ((byte) ((word)(***) & 0xFF))

   #define  WORD_HI(***) ((byte) ((word)(***) >> 8))

10.  将一个字母转换为大写

   #define  UPCASE(c) (((c) >= 'a' && (c)<= 'z') ? ((c) - 0x20) : (c))

11.  判断字符是不是10进值的数字

   #define  DECCHK(c) ((c) >= '0' && (c) <='9')

12.  返回数组元素的个数

   #define  ARR_SIZE(a) (sizeof((a)) / sizeof((a[0])))

13.  对于IO空间映射在存储空间的结构,输入输出处理

   #defineinp(port)         (*((volatile byte *)(port)))

   #defineinpw(port)        (*((volatile word *)(port)))

   #defineinpdw(port)       (*((volatile dword*)(port)))

   #define outp(port,val)   (*((volatile byte *) (port)) = ((byte) (val)))

   #define outpw(port,val)  (*((volatile word *) (port)) =((word) (val)))

   #defineoutpdw(port, val) (*((volatile dword *) (port)) = ((dword) (val)))

14.  使用一些宏跟踪调试

   ANSI标准说明了五个预定义的宏名。它们是:

   __LINE__   (两个下划线),对应%d

   __FILE__   对应%s

   __DATE__   对应%s

   __TIME__   对应%s

   __STDC__

如果编译不是标准的,则可能仅支持以上宏名中的几个,或根本不支持。记住编译程序也许还提供其它预定义的宏名。

   __LINE__宏指令表示当前指令所在的行,是个整型数

   __FILE__宏指令表示当前指令所在文件,包含完整路径

   __DATE__宏指令含有形式为月/日/年的串,表示源文件被翻译到代码时的日期。

   __TIME__宏指令包含源代码翻译到目标代码的时间。串形式为时:分:秒。

   如果实现是标准的,则宏__STDC__含有十进制常量1。如果它含有任何其它数,则实现是非标准的。

可以定义宏,例如:

   当定义了_DEBUG,输出数据信息和所在文件所在行

   #ifdef _DEBUG

       #defineDEBUGMSG(msg,date) printf(msg);printf("%d%d%d",date,_LINE_,_FILE_)

   #else

       #defineDEBUGMSG(msg,date)

   #endif

C、C++宏体中出现的#,#@,##

 

宏体中,#的功能是将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量通过替换后在其左右各加上一个

双引号。

 

而##被称为连接符(concatenator),用来将两个Token连接为一个Token。注意这里连接的对象是Token就行,而不一定是宏的变

量。比如你要做一个菜单项命令名和函数指针组成的结构体的数组,并且希望在函数名和菜单项命令名之间有直观的、名字上的关系。那就可以使用:宏参数##

固定部分。当然还可以n个##符号连接 n+1个Token,这个特性也是#符号所不具备的。

 

#@的功能是将其后面的宏参数进行字符化。

9、C宏中的变参...

 

...在C宏中称为VariadicMacro,也就是变参宏。比如:

 

#define myprintf(templt,...)fprintf(stderr,templt,__VA_ARGS__)

 

或者#definemyprintf(templt,args...) fprintf(stderr,templt,args)

 

第一个宏中由于没有对变参起名,我们用默认的宏__VA_ARGS__来替代它。第二个宏中,我们显式地命名变参为args,那么我们在宏定义中就可以

用args来代指变参了。同C语言的stdcall一样,变参必须作为参数表的最后有一项出现。当上面的宏中我们只能提供第一个参数templt时,C

标准要求我们必须写成:myprintf(templt,);的形式。这时的替换过程为:myprintf("Error!\n",);替换为:

fprintf(stderr,"Error!\n",).

 

这是一个语法错误,不能正常编译。这个问题一般有两个解决方法。首先,GNUCPP提供的解决方法允许上面的宏调用写成:

myprintf(templt);而它将会被通过替换变成:fprintf(stderr,"Error!\n",);

 

很明显,这里仍然会产生编译错误(非本例的某些情况下不会产生编译错误)。除了这种方式外,c99和GNU CPP都支持下面的宏定义方式:

 

#define myprintf(templt, ...) fprintf(stderr,templt,##__VAR_ARGS__)

 

这时,##这个连接符号充当的作用就是当__VAR_ARGS__为空的时候,消除前面的那个逗号。那么此时的翻译过程如下:

myprintf(templt);被转化为: fprintf(stderr,templt);

 

这样如果templt合法,将不会产生编译错误。 

 

 

动态结构体不同,直接比较指针不同

巧用宏定义来增加移植性

#define LIS35DE_delay udelay

#define Delay10us   3

LIS35DE_delay(Delay10us);

Common codes

#if !defined(CONFIG_MACH_GARDA) &&defined(CONFIG_MACH_KYLEVE)

 

#define dev_dbg(dev, format, arg...)

-> ccflags-$(CONFIG_BATTERY_SAMSUNG) := -DDEBUG

 

#define __raw_readl(a) (*(volatile unsigned int *)(a))

#define __raw_writel(v,a) (*(volatile unsigned int *)(a) =(v))

static void __raw_bits_or(unsigned int v, unsigned int a)

{

        __raw_writel((__raw_readl(a)| v), a);

}

 

 

结构体初始化

static struct iio_chan_spec iio_dummy_channels[] = {

        /* indexed ADCchannel in_voltage0_raw etc */

        {

                       .type= IIO_VOLTAGE,

                       .scan_type= { /* Description of storage in buffer */

                                      .sign= 'u', /* unsigned */

                                      .realbits= 13, /* 13 bits */

                       },

        }

}

结构体定义默认值

struct iio_chan_spec {

        const char                          *datasheet_name;

        unsigned                             processed_val:1;

        unsigned                             modified:1;

};

 

安全字符串处理函数

strlcat

strlcpy

 

设置和查询某些bit位

#define set_bit(nr,p)                               ATOMIC_BITOP(set_bit,nr,p)

#define clear_bit(nr,p)                                          ATOMIC_BITOP(clear_bit,nr,p)

#define change_bit(nr,p)                       ATOMIC_BITOP(change_bit,nr,p)

#define test_and_set_bit(nr,p)                           ATOMIC_BITOP(test_and_set_bit,nr,p)

#define test_and_clear_bit(nr,p)         ATOMIC_BITOP(test_and_clear_bit,nr,p)

#define test_and_change_bit(nr,p)     ATOMIC_BITOP(test_and_change_bit,nr,p)

 

likely() 与unlikely()

BTW, !!x means translate the value of x to 0 OR 1.

From /include/linux/compiler.h

#define likely(x) __builtin_expect(!!(x), 1)

#define unlikely(x) __builtin_expect(!!(x), 0)

 

__builtin_expect is builtin function of GCC.

In GCC manual, it said that You may use __builtin_expect toprovide the compiler with branch prediction information.

Ref: #define likely(x) __builtin_expect(!!(x), 1)也就是说明x==1是“经常发生的”或是“很可能发生的”。使用likely,执行if后面语句的可能性大些,编译器将if{}是的内容编译到前面,使用unlikely,执行else后面语句的可能性大些,编译器将else{}里的内容编译到前面。这样有利于cpu预取,提高预取指令的正确率,因而可提高效率。总之,likely与unlikely互换或不用都不会影响程序的正确性。但可能会影响程序的效率。

 

 

结构体和位域的结合

应用场景:直接将32-bit的结构体赋值成32-bit的寄存器,这样直接可以用位域来访问某个bit

typedef union usb_intsts_tag

{

    structusb_intsts_map

    {

        volatileunsigned int curmod            :1; 

        volatileunsigned int modemis           :1;

        volatileunsigned int otgint            :1;

        volatileunsigned int sof               :1;

........

                       volatileunsigned int conidstschng      :1;

                       volatileunsigned int discoonint                       :1;      //Deviceenable ;

                       volatileunsigned int sessreqint                       :1;      //Slefpowered ;

                       volatileunsigned int wkupint         :1;//Reserved ;

  

    } mBits ;

    volatile unsignedint dwValue ;

} USB_INTSTS_U;

 

C/CPP/Assembly Cross

 

 

variable in C and Assembly code

         In *.S

         ldr     r0, .Lrestore_pblist

         .Lrestore_pblist:               .long   restore_pblist

         In *.c

         struct pbe*restore_pblist;

 

汇编程序访问C语言全局变

全局变量只能通过地址间接调用,为了访问C语言中全局变量,首先要通过extern伪指令引入全局变量,然后将其地址装入寄存器中。

对于unsigned char类型,使用LDRB/STRB访问;

对于unsigned short类型,使用LDRH/STRH访问;

对于unsigned int类型,使用LDR/STR访问;

对于char类型,使用LDRSB/STRSB访问;

对于short类型,使用LDRSH/STRSH访问;

例子:

.text

.global asmsubroutine

.extern globvar

asmsubroutine

LDR R1,=globvar

LDR R0,[R1]

ADD R0,R0,#2

STR R0,[R1]

MOV PC,LR

.end

C invoke Assemble

C程序调用汇编程序首先通过extern声明要调用的汇编程序模块,声明中形参个数要与汇编程序模块中需要的变量个数一致,且参数传递要满足ATPCS规则,然后在C程序中调用。

例子:

#include<stdio.h>

extern void *strcopy(char*d,char*s);//模块声明

int main()

{

char*srcstr="first";

char*dststr="second";

strcopy(dststr,srcstr);//汇编模块调用;

}

.text

.global strcopy

Strcopy:

LDRB R2,[R1],#1

STRB R2,[R0],#1

CMP R2,#0

BNE Sstcopy

MOV PC,LR

.end

Sample : C call Assembly

         In *.c

         externasmlinkage int swsusp_arch_resume(void);

         xxx { error =swsusp_arch_resume();  }

         In *.S

         ENTRY(swsusp_arch_resume)

ENDPROC(swsusp_arch_resume)

 

Assemble invoke C

在调用之前必须根据C语言模块中需要的参数个数,以及ATPCS参数规则,完成参数传递,即前四个参数通过R0-R3传递,后面的参数通过堆栈传递,然后再利用BBL指令调用。

例子:

int g(int a,int b,int c,int d,int e)//C语言函数原型

{

return(a+b+c+d+e);

}

汇编语言完成是求i+2i+3i+4i+5i的结果;

.global _start

.text

_start:

.extern g   ;引入c程序

STR LR,{SP,-#4}!;保存PC

ADD R1,R0,R0

ADD R2,R1,R0

ADD R3,R1,R2

STR R3,{SP,#-4}!

ADD R3,R1,R1

BL g   ;调用C函数g

ADD SP,SP,#4

LDR PC,[SP],#4

.end

return(0);

Sample :  Assembly call C

         In *.c

         asmlinkage int_restore_svc(void)

{

       printk(KERN_INFO "[JC]%s\n", __func__);

        return 0;

}

         In *.S

         bl      _restore_svc

 

NOTE:

  7 #ifdef __cplusplus

  8 #defineCPP_ASMLINKAGE extern "C"

  9 #else

 10 #defineCPP_ASMLINKAGE

 11 #endif

 12

 13 #ifndef asmlinkage

 14 #define asmlinkageCPP_ASMLINKAGE

 15 #endif

 

 

 

Extern “C” (CPP call C)

extern "C"指令描述的是一种链接约定,它并不影响调用函数的定义,即时做了该声明,对函数类型的检查和参数转换仍要遵循C++的标准,而不是C

 

C++中调用C库

1).做一个C动态库:

 

 

// hello.c:

 

#include <stdio.h>

 

void hello()

{

 printf("hello\n");

}

 

 

2).写个C++程序去调用它:

 

// test.cpp

 

#include <iostream>

 

#ifdef __cplusplus

extern "C" {               // 告诉编译器下列代码要以C链接约定的模式进行链接

#endif

 

void hello();

 

#ifdef __cplusplus

}

#endif

 

int main()

{

  hello();

 

  return 0;

}

C调用C++

1)做一个C++库:

 

 

// world.cpp

 

#include <iostream>

 

void world()

{

  std::cout <<"world" << std::endl;

}

 

编译并copy到系统库目录下:

[root@coredump test]# g++ --shared -o libworld.so world.cpp

[root@coredump test]# cp libworld.so /lib/

2)做一个中间接口库,对C++库进行二次封装:

 

 

// mid.cpp

 

#include <iostream>

 

void world();

 

#ifdef __cplusplus

extern "C" { // 即使这是一个C++程序,下列这个函数的实现也要以C约定的风格来搞!

#endif

 

  void m_world()

  {

    world();

  }

 

#ifdef __cplusplus

}

#endif

 

其中方法m_world即为libworld库中world方法的二次封装,编译并copy到系统库目录下:

[root@coredump test]# g++ --shared -o libmid.so mid.cpp -lworld

[root@coredump test]# cp libmid.so /lib/

3).C程序通过链接二次接口库去调用C++库:

 

 

// test.c

 

#include <stdio.h>

 

int main()

{

  m_world();

 

  return 0;

}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值