c_插件 - CSDN
c 订阅
C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方式编译、处理低级存储器。C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言。尽管C语言提供了许多低级处理的功能,但仍然保持着跨平台的特性,以一个标准规格写出的C语言程序可在包括类似嵌入式处理器以及超级计算机等作业平台的许多计算机平台上进行编译。 [1] 展开全文
C语言是一门面向过程的、抽象化的通用程序设计语言,广泛应用于底层开发。C语言能以简易的方式编译、处理低级存储器。C语言是仅产生少量的机器语言以及不需要任何运行环境支持便能运行的高效率程序设计语言。尽管C语言提供了许多低级处理的功能,但仍然保持着跨平台的特性,以一个标准规格写出的C语言程序可在包括类似嵌入式处理器以及超级计算机等作业平台的许多计算机平台上进行编译。 [1]
信息
类    别
程序设计语言
影响语言
C++、C#、D、Java、JavaScript、ObjectPHP等
创始时间
1972年
主要编译器
Visual C++、Clang、GCC、Turbo C等
中文名
C语言
创始人
Dennis MacAlistair Ritchie
发    源
BCPL语言
外文名
C Programming Language
c语言简介
C语言是一门面向过程的计算机编程语言,与C++、Java等面向对象编程语言有所不同。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、仅产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。C语言描述问题比汇编语言迅速、工作量小、可读性好、易于调试、修改和移植,而代码质量与汇编语言相当。C语言一般只比汇编语言代码生成的目标程序效率低10%~20%。因此,C语言可以编写系统软件。 [2]  当前阶段,在编程领域中,C语言的运用非常之多,它兼顾了高级语言和汇编语言的优点,相较于其它编程语言具有较大优势。计算机系统设计以及应用程序编写是C语言应用的两大领域。同时,C语言的普适较强,在许多计算机操作系统中都能够得到适用,且效率显著。 [3]  冯.诺依曼在1945年提出了现代计算机的若干思想,被后人称为冯.诺依曼思想,这是计算机发展史上的里程碑。自1945 年至今大多采用其结构,因此冯.诺依曼被称为计算机之父。他的体系结构计算机由运算器、控制器、存储器、输入设备、输出设备五大部件构成。 C语言拥有一套完整的理论体系经过了漫长的发展历史,在编程语言中具有举足轻重的地位。 [4] 
收起全文
  • C语言和C++的区别

    2018-08-02 00:12:40
    现在我们常用的C语言C89标准,C++是C++99标准的。C89就是在1989年制定的标准,如今最新的是C11和C++11标准。根据不同的标准,它们的功能也会有所不同,但是越新的版本支持的编译器越少,所以本文在讨论的时候使用...

    c语言虽说经常和c++在一起被大家提起,但可千万不要以为它们是一个东西。现在我们常用的C语言是C89标准,C++是C++99标准的。C89就是在1989年制定的标准,如今最新的是C11和C++11标准。根据不同的标准,它们的功能也会有所不同,但是越新的版本支持的编译器越少,所以本文在讨论的时候使用的C语言标准是C89,C++标准是C++99.我们来介绍C语言和C++中那些不同的地方。

    • 1.函数默认值

    在C++中我们在定义或声明一个函数的时候,有时会在形参中给它赋一个初始值作为不传参数时候的缺省值,例如:

    int FUN(int a = 10);

    代表没有传参调用的时候,自动给a赋一个10的初始值。然而这种操作在c89下是行不通的,在c语言下这么写就会报错。

    我们都知道,系统在调用任何一个函数的时候都有函数栈帧的开辟,如果函数有参数则需要压入实参。平常在我们人为给定实参的时候,是按照参数列表从右向左依次将参数通过

    mov  eax/ecx   dword ptr[ebp-4]       //假设是int数据

    指令传入寄存器,再通过push指令压入。现在我们已经给定了函数参数的默认值,那么在压实参的时候只需要一步push初始值即可。效率更高。

    另外需要注意的是,赋初始值必须从参数列表的右边开始赋值,从左边开始赋值将会出错:

    int sum1(int a = 10,int b);        //错误
    int sum2(int a,int b = 20);            //正确
    

    因为如果sum1的声明是正确的,那么我们调用的时候怎么调用?sum1( ,20)?很可惜这样属于语法错误,调用这么写既然不对那就当然不能这样赋初始值了。相反,sum2的调用:sum2(20);合情合理,没有任何问题。

    实际在写工程的时候,我们都习惯将函数的声明写在头文件中而非本文件里,然后在不同的文件中写出它们的定义。那么这种情况可以赋初始值吗?当然可以,不论是定义还是声明处,只要你遵守从右向左赋的规则就可以。甚至你还可以这样给初始值:

    int  fun(int a ,int b = 10);
    int  fun(int a = 20,int b);

    眼尖的同学看见了下面的那行代码大喊错误,因为先给左边赋值了!

    其实这样声明完全没有问题,两句声明是同一个函数(函数多次声明没有问题),第一句已经给b了一个初始值,运行到第二句时已经等价于int fun(int a = 20,int b = 10);了。但是注意,这两句的顺序不能反转,否则就是错误的。

     

    总结:C89标准的C语言不支持函数默认值,C++支持函数默认值,且需要遵循从右向左赋初始值。

     

    • 2.inline内联函数

    说到内联函数大家应当不陌生,它又是一个C89标准下C语言没有的函数。它的具体做法和宏非常相似,也是在调用处直接将代码展开,只不过宏它是在预编译阶段展开,而内联函数是在 编译阶段进行处理的。同时,宏作为预处理并不进行类型检查,而inline函数是要进行类型检查的,也就可以称作“更安全的宏”。

    内联函数和普通函数的区别:内联函数没有栈帧的开辟回退,一般我们直接把内联函数写在头文件中,include之后就可以使用,由于调用时直接代码展开所以我们根本不需要担心什么重定义的问题——它连符号都没有生成当然不会所谓重定义了。普通函数生成符号,内联函数不会生成符号。

    关于inline还需要注意的一点是,我们在使用它的时候往往是用来替换函数体非常小(1~5行代码)的函数的。这种情况下函数的堆栈开销相对函数体大小来说就非常大了,这种情况使用内联函数可以大大提高效率。相反如果是一个需要很多代码才能实现的函数,则不适合使用。一是此时函数堆栈调用开销与函数体相比已经是微不足道了,二是大量的代码直接展开的话会给调试带来很大的不便。三是如果代码体达到一个阈值,编译器会将它变成普通函数。

    同时,递归函数不能声明为inline函数。说到底inline只是对编译器的建议,最终能否成功也不一定。同时,我们平常生成的都是debug版本,在这个版本下inline是不起作用的。只有生成release版时才会起作用。

    总结:C89没有,在调用点直接展开,不生成符号,没有栈帧的开辟回退,仅在Release版本下生效。一般写在头文件中。

     

    • 3.函数重载

    C语言中产生函数符号的规则是根据名称产生,这也就注定了c语言不存在函数重载的概念。而C++生成函数符号则考虑了函数名、参数个数、参数类型。需要注意的是函数的返回值并不能作为函数重载的依据,也就是说int sum和double sum这两个函数是不能构成重载的!

    我们的函数重载也属于多态的一种,这就是所谓的静多态。

    静多态:函数重载,函数模板

    动多态(运行时的多态):继承中的多态(虚函数)。

    使用重载的时候需要注意作作用域问题:请看如下代码。

    #include <iostream>
    
    using namespace std;
    
    bool compare(int a,int b)
    {
        return a > b;
    }
    
    bool  compare(double a,double b)
    {
        return a > b;
    }
    
    int main()
    {
        //bool compare(int a,int b);
        compare(10,20);
        compare(10.5,20.5);
        return 0;
    }
    

    我在全局作用域定义了两个函数,它们由于参数类型不同可以构成重载,此时main函数中调用则可以正确的调用到各自的函数。

    但是请看main函数中被注释掉的一句代码。如果我将它放出来,则会提出警告:将double类型转换成int类型可能会丢失数据。

    这就意味着我们编译器针对下面两句调用都调用了参数类型int的compare。由此可见,编译器调用函数时优先在局部作用域搜索,若搜索成功则全部按照该函数的标准调用。若未搜索到才在全局作用域进行搜索。

     

    总结:C语言不存在函数重载,C++根据函数名参数个数参数类型判断重载,属于静多态,必须同一作用域下才叫重载。

     

    • 4.const

     

    这一部分非常重要。在我的另一篇博客“C语言的32个关键字”中对C语言中的const也有所讲解。当中提到了这么一个问题:C语言中被const修饰的变量不是常量,叫做常变量或者只读变量,这个常变量是无法当作数组下标的。然而在C++中const修饰的变量可以当作数组下标使用,成为了真正的常量。这就是C++对const的扩展。

    C语言中的const:被修饰后不能做左值,可以不初始化,但是之后没有机会再初始化。不可以当数组的下标,可以通过指针修改。简单来说,它和普通变量的区别只是不能做左值而已。其他地方都是一样的。

    C++中的const:真正的常量。定义的时候必须初始化,可以用作数组的下标。const在C++中的编译规则是替换(和宏很像),所以它被看作是真正的常量。也可以通过指针修改。需要注意的是,C++的指针有可能退化成C语言的指针。比如以下情况:

    int b = 20;
    const int a = b;

    这时候的a就只是一个普通的C语言的const常变量了,已经无法当数组的下标了。(引用了一个编译阶段不确定的值)

    const在生成符号时,是local符号。即在本文件中才可见。如果非要在别的文件中使用它的话,在文件头部声明:extern cosnt int data = 10;这样生成的符号就是global符号。

    总结:C中的const叫只读变量,只是无法做左值的变量;C++中的const是真正的常量,但也有可能退化成c语言的常量,默认生成local符号。

     

    • 5.引用

    说到引用,我们第一反应就是想到了他的兄弟:指针。引用从底层来说和指针就是同一个东西,但是在编译器中它的特性和指针完全不同。

        int a = 10;
    	int &b = a;
    	int *p = &a;
    
    	//b = 20;
    	//*p = 20;

    首先定义一个变量a = 10,然后我们分别定义一个引用b以及一个指针p指向a。我们来转到反汇编看看底层的实现:

    可以看到底层实现完全一致,取a的地址放入eax寄存器,再将eax中的值存入引用b/指针p的内存中。至此我们可以说(在底层)引用本质就是一个指针。

    了解了底层实现,我们回到编译器。我们看到对a的值的修改,指针p的做法是*p = 20;即进行解引用后替换值。底层实现:

    再来看看引用修改:

    我们看到修改a的值的方法也是一样的,也是解引用。只是我们在调用的时候有所不同:调用p时需要*p解引用,b则直接使用就可以。由此我们 推断出:引用在直接使用时是指针解引用。p直接使用则是它自己的地址。

    这样我们也了解了,我们给引用开辟的这块内存是根本访问不到的。如果直接用就直接解引用了。即使打印&b,输出的也是a的地址。

    在此附上将指针转为引用的小技巧:int *p = &a,我们将 引用符号移到左边 将 *替换即可:int &p = a。

    接下来看看如何创建数组的引用:

    int array[10] = {0};       //定义一个数组

    我们知道,array拿出来使用的话就是数组array的首元素地址。即是int *类型。

    那么&array是什么意思呢?int **类型,用来指向array[0]地址的一个地址吗?不要想当然了,&array是整个数组类型。

    那么要定义一个数组引用,按照上面的小诀窍,先来写写数组指针吧:

    int (*q) [10] = &array;

    将右侧的&对左边的*进行覆盖:

    int (&q)[10] = array;

    测试sizeof(q) = 10。我们成功创建了数组引用。

     

    经过上面的详解 ,我们知道了引用其实就是取地址。那么我们都知道一个立即数是没有地址的,即

    int &b = 10;

    这样的代码是无法通过编译的。那如果你就是非要引用一个立即数,其实也不是没有办法:

    const int &b  = 10;

    即将这个立即数用const修饰一下,就可以了。为什么呢?

    这时因为被const修饰的都会产生一个临时量来保存这个数据,自然就有地址可取了。

     

    总结:引用底层就是指针,使用时会直接解引用,可以配合const对一个立即数进行引用。

     

    • 6.malloc,free && new,delete

    这个问题很有意思,也是重点需要关注的问题。malloc()和free()是C语言中动态申请内存和释放内存的标准库中的函数。而new和delete是C++运算符、关键字。new和delete底层其实还是调用了malloc和free。它们之间的区别有以下几个方面:

    ①:malloc和free是函数,new和delete是运算符。

     

    ②:malloc在分配内存前需要大小,new不需要。

    例如:int *p1 = (int *)malloc(sizeof(int));

               int *p2 = new int;     //int *p3 = new int(10);

    malloc时需要指定大小,还需要类型转换。new时不需要指定大小因为它可以从给出的类型判断,并且还可以同时赋初始值。

     

    ③:malloc不安全,需要手动类型转换,new不需要类型转换。

    详见上一条。

     

    ④:free只释放空间,delete先调用析构函数再释放空间(如果需要)。

    与第⑤条对应,如果使用了复杂类型,先析构再call operator delete回收内存。

     

    ⑤:new是先调用构造函数再申请空间(如果需要)。

    与第④条对应,我们在调用new的时候(例如int *p2 = new int;这句代码 ),底层代码的实现是:首先push 4字节(int类型的大小),随后call   operator new函数分配了内存。由于我们这句代码并未涉及到复杂类型(如类类型),所以也就没有构造函数的调用。如下是operator new的源代码,也是new实现的重要函数:

    void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
            {       // try to allocate size bytes
            void *p;
            while ((p = malloc(size)) == 0)
                    if (_callnewh(size) == 0)
                    {       // report no memory
                            _THROW_NCEE(_XSTD bad_alloc, );
                    }
     
            return (p);
            }

    我们可以看到,首先malloc(size)申请参数字节大小的内存,如果失败(malloc失败返回0)则进入判断:如果_callnewh(size)也失败的话,抛出bad_alloc异常。_callnewh()这个函数是在查看new handler是否可用,如果可用会释放一部分内存再返回到malloc处继续申请,如果new handler不可用就会抛出异常。

     

    ⑥:内存不足(开辟失败)时处理方式不同。

    malloc失败返回0,new失败抛出bad_alloc异常。

     

    ⑦:new和malloc开辟内存的位置不同。

    malloc开辟在堆区,new开辟在自由存储区域。

     

    ⑧:new可以调用malloc(),但malloc不能调用new。

    new就是用malloc()实现的,new是C++独有malloc当然无法调用。

    • 7.作用域

    C语言中作用域只有两个:局部,全局。C++中则是有:局部作用域,类作用域,名字空间作用域三种。

    所谓名字空间就是namespace,我们定义一个名字空间就是定义一个新作用域。访问时需要以如下方式访问(以std为例)

    std::cin<< "123" <<std::endl;

    例如我们有一个名字空间叫Myname,其中有一个变量叫做data。如果我们希望在其他地方使用data的话,需要在文件头声明:using Myname::data;这样一来data就使用的是Myname中的值了。可是这样每个符号我们都得声明岂不是累死?

    我们只要using namespace Myname;就可以将其中所有符号导入了。

    这也就是我们经常看到的using namespace std;的意思啦。

    展开全文
  • c语言中有一个重点:c指针。它也是一个难点。当然,这是一句废话:重点往往也是难点。在c标准中,对指针的定义是这样的: 指针的类型是derived from其它类型,也就是说指针的类型是由它指向的类型决定的; 指针是一...

                         (0)c语言的梦魇:c指针

                                序

        c语言中有一个重点:c指针。它也是一个难点。当然,这是一句废话:重点往往也是难点。在c标准中,对指针的定义是这样的:

    1. 指针的类型是derived from其它类型,也就是说指针的类型是由它指向的类型决定的;
    2. 指针是一种reference类型,即引用类型;

        c指针似乎很难理解,以至于有人指出:掌握了c指针,就掌握了c语言的精髓。本系列就来聊聊c指针,要想弄懂c指针。光就指针本身进行理解,还不够。

        因为指针的本质就一句话:指针就是地址。这句话大多数学过c语言的人都明白,但对很多使用指针的场景仍然是不知所措,就像梦魇一样。必须指出:指针之所以难理解,更多地在于c的语法。可以明确指出c的语法很多时候是不太自然的,混乱的。毕竟c语言是人设计的,有所缺陷或者说设计不佳,在所难免。

        这并不是否定c语言的魅力和能力。相反,c语言的确是强大的,在底层的操作上也许仅次于汇编。但要想发挥出c语言的强大能力,前提是必须对语言本身有深刻的理解。从c语言的发展史看,c语言起源于B语言,接着演化为New B,简称NB,再就是今天的c语言。c语言就是一门介于NA和NC之间的语言!

    本系列集中探讨以下问题:

    1. 指针和数组为何如此暧昧?
    2. c语言中变量的可见域、生存期
    3. 变量的左值、右值
    4. 什么是静态函数?
    5. c语言中的复杂申明如何解析?
    6. 数组的数组是什么意思?
    7. const的使用
    8. typedef是用来干什么的?
    9. 结构体的使用
    10. ……

    个人能力有限,预计本系列会很艰难。但能往前走一步,就绝不走半步。本系列以c指针为中心,加以c的语法解析。欢迎各路高手批评指正。

                                                                    David

                                                                    2014年7月23日


    目录

    1. 指针就是地址
    2. 内存分配
    3. 指针和数组
    4. 解析c的声明语句
    5. c数组本质
    6. const的使用
    7. 指针运算
    8. 开发可变参数函数



    所有内容的目录


    展开全文
  • 小猪的C语言快速入门系列(七)标签: C语言本节引言:在第五节的时候我们对C里的指针进行了初步的学习,而作为C语言的灵魂, 当然不会就那么简单,本节我们来进一步学习指针,包括:函数与指针, 指针数组,二级...

    小猪的C语言快速入门系列(七)

    标签: C语言


    本节引言

    在第五节的时候我们对C里的指针进行了初步的学习,而作为C语言的灵魂,
    当然不会就那么简单,本节我们来进一步学习指针,包括:函数与指针
    指针数组二级指针内存的动态 以及 const修饰指针


    本节学习路线图


    1.函数与指针


    1)指针作为函数的形参

    2)指向函数的指针

    3)指针函数

    4)带参数的主函数

    该程序需要用到命令行参数,需要先编译生成exe,然后cmd命令行来到生成的exe文件
    所在目录下输入:文件名 one two three,结果会输出one two three。


    2.指针数组

    问题引入:如何保存一个字符串更好?如果保存的不止一个,而是多个字符串呢?

    问题一回答

    char name[20] = “~” ②char *name = “~” //前者定义了长度,不能直接赋值,明显后者比较灵活

    问题二回答


    3.二级指针


    4.内存的动态分配

    代码示例

    动态分配10个int类型的空间大小,如果大于这个数目则动态分配,否则利用realloc
    重新分配内存。

    #include <stdio.h>  
    #include <stdlib.h>  
    #define N 10  
    
    int main()  
    {  
        int *p = 0;  
        int  i,num,*q = 0;  
        p = (int *)malloc((N * sizeof(int)));  
        if(p == 0)  
        {  
            printf("内存分配错误!\n");  
            exit(0);  
        }  
        printf("请输入要存储的元素个数:\n");  
        scanf("%d",&num);  
        if(num <= N)  
        {  
            for(i = 0;i < N;i++)  
            scanf("%d",p+i);  
        }  
        else  
        {  
            for(i = 0;i < num;i++)  
            q = (int *)realloc(p,(N + N)*sizeof(int));  
            if(q == 0)exit(0);  
            for(i = 0;i < num;i++)  
            scanf("%d",q + i);  
            p = q;  
        }  
        for(i = 0;i < num;i++)  
        printf("%3d",*(p+i));  
    
        printf("\n");  
        free(p);  
        return 0;     
    }

    5.使用const修饰指针变量

    const 关键字修饰的数据类型是指 常类型,最简单的用法是用来定义const
    常量,具有不变性,比如int const a = 10; 要注意一点:
    const修饰的常量在声明的时候就要进行初始化赋值,不然后面是不能赋值的!

    另外在与指针结合使用的时候,const 颠倒写 表示的意思是不一样的!

    • int const *a; //修饰指向的内容,a可变,a指向的内容不可变
    • int *const a; //修饰指针a,a不可变,a指向的内容可变
    • const int *a; //修饰指向的内容,a可变,a指向的内容不可变
    • const int *const A; //指针a和a指向的内容都不可变

     
    上述结论可以自行修改下述例子里指针与指向的内容自行测试:

    #include<stdio.h>
    int main()
    {
        int const a;
        a = 5;
        printf("a = %d\n",a);
        return 0;
    }

    本文链接小猪的C语言快速入门系列(七)
    作者:Coder-Pig
    出处http://blog.csdn.net/coder_pig
    本文基于知识共享署名-相同方式共享 4.0 国际许可协议发布,欢迎转载,
    演绎或用于商业目的,但是必须保留本文的署名及链接。åç


    展开全文
  • 1、C调用C++ 本文给出了一种方法。基本思想是,写一个 wrapper文件,把 C++类封装起来,对外只提供C语言的接口,和 C++i相关的都在 wrapper的实现文件里实现。 //------apple.h #ifndef __APPLE_H__ #define __...

    1、C调用C++

    本文给出了一种方法。基本思想是,写一个 wrapper文件,把 C++类封装起来,对外只提供C语言的接口,和 C++i相关的都在  wrapper的实现文件里实现。

    //------apple.h
    #ifndef __APPLE_H__
    #define __APPLE_H__
    class Apple
    {
    public:
        enum
        {
            APPLE_COLOR_RED,
            APPLE_COLOR_BLUE,
            APPLE_COLOR_GREEN,
        };
     
        Apple();
        int GetColor(void);
        void SetColor(int color);
    private:
        int m_nColor;
    };
    #endif 
    
    //-----apple.cpp:
    #include "apple.h"
    Apple::Apple():m_nColor(APPLE_COLOR_RED)
    {
    }
     
    void Apple::SetColor(int color)
    {
        m_nColor = color;
    }
     
    int Apple::GetColor(void)
    {
        return m_nColor;
    }
    //-----AppleWrapper.h
    #ifndef _APPLE_WRAPPER_H__
    #define _APPLE_WRAPPER_H_
    struct tagApple;
    #ifdef __cplusplus
    extern "C" {
    #endif
    struct tagApple *GetInstance(void);
    void ReleaseInstance(struct tagApple **ppInstance);
    extern void SetColor(struct tagApple *pApple, int color);
    extern int GetColor(struct tagApple *pApple);
    #ifdef __cplusplus
    };
    #endif
    #endif
    //-----AppleWrapper.cpp
    #include "AppleWrapper.h"
    #include "apple.h"
     
    #ifdef __cplusplus
    extern "C" {
    #endif
    struct tagApple
    {
        Apple apple;
    };
    struct tagApple *GetInstance(void)
    {
        return new struct tagApple;
    }
    void ReleaseInstance(struct tagApple **ppInstance)
    {
        delete *ppInstance;
        *ppInstance = 0;
        
    }
    void SetColor(struct tagApple *pApple, int color)
    {
        pApple->apple.SetColor(color);
    }
     
    int GetColor(struct tagApple *pApple)
    {
        return pApple->apple.GetColor();
    }
    #ifdef __cplusplus
    };
    #endif
    //-----test.c
    #include "AppleWrapper.h"
    #include <assert.h>
     
    int main(void)
    {
        struct tagApple * pApple;
        pApple= GetInstance();
        SetColor(pApple, 1);
        int color = GetColor(pApple);
        printf("color = %d\n", color);
        ReleaseInstance(&pApple);
        assert(pApple == 0);
        return 0;
    }

    可以用 GCC编译:
    g++ -c apple.cpp
    g++ -c apple.cpp  AppleWrapper.cpp
    gcc test.c -o test AppleWrapper.o apple.o -lstdc++

    其实,  wrapper里的 struct 完全可以不要,定义一个  handle更好:

    //-----AppleWrapper.h
    #ifndef _APPLE_WRAPPER_H__
    #define _APPLE_WRAPPER_H_
    #ifdef __cplusplus
    extern "C" {
    #endif
    int  GetInstance(int *handle);
    void ReleaseInstance(int *handle);
    extern void SetColor(int handle, int color);
    extern int GetColor(int handle);
    #ifdef __cplusplus
    };
    #endif
    #endif
    //-----AppleWrapper.cpp
    #include "AppleWrapper.h"
    #include "apple.h"
    #include <vector>
     
    #ifdef __cplusplus
    extern "C" {
    #endif
     
    static std::vector<Apple *> g_appleVector;
     
    int GetInstance(int * handle)
    {
        g_appleVector[0] =  new Apple;
        *handle = 0;
        return 1;
    }
    void ReleaseInstance(int *handle)
    {
        delete g_appleVector[*handle];
        *handle = -1;
        
    }
    void SetColor(int handle, int color)
    {
        g_appleVector[handle]->SetColor(color);
    }
     
    int GetColor(int handle)
    {
        return g_appleVector[handle]->GetColor();
    }
    #ifdef __cplusplus
    };
    #endif

    2、C++调用C函数实例

    // --------------cfun.h
    #ifndef __C_FUN_20180228_H__
    #define __C_FUN_20180228_H__
     
    #ifdef __cplusplus
    extern "C"{
    #endif // __cplusplus
     
        void cfun();
    #ifdef __cplusplus
    }
    #endif
     
     
    #endif


    cfun.h头文件中,使用了条件编译#ifdef __cplusplus, 表示如果是C++来调用该接口,则该函数接口经编译后的函数符号生成规则按照C风格走, 否则没有extern "C" , 这样提供的接口同时支持C和C++两者的调用。

    // --------------cfun.c
    #include "cfun.h"
    #include <stdio.h>
     
    void cfun()
    {
        printf("hello world.\n");
    }
    
    // --------------main.cpp
    #include <iostream>
    #include "cfun.h"
     
     
    int main()
    {
        cfun();
        system("pause");
        return 0;
    }

     

    展开全文
  • 1、C/C++中的正则表达式 标准的C和C++都不支持正则表达式的使用,但是在某些场景下正则表达式的存在可以为程序员带来很大的遍历,比如用户注册中对用户名和密码的判断,看是否符合命名规则。 虽然不支持,但是有...
  • 函数被C++编译后在库中的名字与C语言的不同,C++和C是两种完全不同的编译链接处理方式,如果直接在C++里面调用C函数,会找不到函数体,报链接错误,解决办法:加 extern “C”,示例如下: VS2015新建win32...
  • JSON是一种比XML更轻量级的数据交换格式,关于JSON的基础知识,参考 JSON ... 看看你使用的语言中是否已有JSON... cJSON是C语言中的一个JSON编解码器,非常轻量级,C文件只有500多行,速度也非常理想。项目主页:cJS
  • c语言求ax^2+bx+c=0方程的解。#include <stdio.h>#include <math.h>#define m 0.000001int main(){ float a,b,c,x,x2,n,q,p; scanf ("%f%f%f",&a,&b,&c); n=b*b-4*a*c;...
  • 小猪的C语言快速入门系列(三)标签: C语言本节引言:在上一节中,对C语言的基本语法进行了学习,类比成学英语的话,我们现在 只是会单词而已,组成一个个句子还需要学习一些语法,本节学习的就是两对 输入输出函数...
  • 配置VScode c语言环境

    2018-08-03 07:18:45
    成成最近用到C语言了,之前比较喜欢用在vscode上面用python调试,今天我参考了一些文章,也尝试了下在vscode上配置c语言的调试,其中包含一些相关的基础知识。 1、在vscode里面下载c/c++官方插件: 2、安装c/c++...
  • C语言视频培训教程,本课程属于C语言编码技能提高篇,帮助学习过C语言的人,更上一个台阶。课程内容涉及:C语言类型转化、深入理解二维数组、指针、二级指针及多级指针、回调函数、双向链表、排序、贪吃蛇项目案例...
  • //求方程ax^2+bx+c=0的根 #include #include int main() { float a,b,c,dis,x1,x2; printf("请输入a,b,c的值: "); scanf("%f %f %f",&a,&b,&c); dis=b*b-4*a*c; if(dis) { printf("该函数无实根。\n"); ...
  • 本文更好的排版方式:使用Notepad++开发C程序 本文介绍的是Notepad++(编辑器)与MinGW(工具集,包含gcc)结合使用的一种C语言开发环境。 安装包链接: https://pan.baidu.com/s/1nMxMZpyRJUwszlVsmy_fcA 提取...
  • 要理解.c文件与.h文件有什么不同之处,首先需要弄明白编译器的工作过程,一般说来编译器会做以下几个过程: 1.预处理阶段 2.词法与语法分析阶段 3.编译阶段,首先编译成纯汇编语句,再将之汇编成跟CPU相关的二进制码,...
  • C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现过程...
  • C语言实验——合法的C标识符Time Limit: 1000 ms Memory Limit: 65536 KiB Submit Statistic Discuss Problem Description 给出一个标识符,请你判断它是否是C语言合法的标识符。...
  • C语言有以下几种取整方法: 1、直接赋值给整数变量。如: int i = 2.5; 或 i = (int) 2.5; 这种方法采用的是舍去小数部分。 2、C/C++中的整数除法运算符"/"本身就有取整功能(int / int),而下面介绍的...
  • 问题描述:用*号输出字母C的图案。 问题分析:可先用'*'号在纸上写出字母C,大小自行设定,再分行输出。 程序源码: #include&lt;stdio.h&gt; int main() { printf("Hello C-world!\n"); ...
  • C语言是面向过程的,而C++是面向对象的 C和C++的区别: C是一个结构化语言,它的重点在于算法和数据结构。C程序的设计首要考虑的是如何通过一个过程,对输入(或环境条件)进行运算处理得到输出(或实现过程...
1 2 3 4 5 ... 20
收藏数 10,591,959
精华内容 4,236,783
关键字:

c