Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/125.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从C++;到C 在C++中编码了几年之后,我在C语言中提供了一个作业编码,在嵌入式领域。 撇开C++在嵌入式领域中的错误与否,是否有一些特点/习语在C++中会被忽略。仅举几个例子: 通用的、类型安全的数据结构(使用模板) 拉伊。尤其是在具有多个返回点的函数中,例如,不必记住在每个返回点上释放互斥 一般的析构函数。也就是说,您为MyClass编写了一次d'tor,然后,如果MyClass实例是MyOtherClass的成员,MyOtherClass不必显式地取消初始化MyClass实例—它的d'tor将自动调用 名称空间 你从C++到C的经历是什么? 对于你最喜欢的C++特征/习语,你找到了哪些替代品?你发现C++有什么特性吗?< /P> < P>观察到的< < LI>除非你计划使用C++编译器来编译C(如果你坚持C++的一个好的子集,你很可能会发现C++中编译器允许的东西,那就是C++中的编译错误)。 没有更多神秘的模板错误(耶!) 没有(语言支持的)面向对象编程_C++_C - Fatal编程技术网

从C++;到C 在C++中编码了几年之后,我在C语言中提供了一个作业编码,在嵌入式领域。 撇开C++在嵌入式领域中的错误与否,是否有一些特点/习语在C++中会被忽略。仅举几个例子: 通用的、类型安全的数据结构(使用模板) 拉伊。尤其是在具有多个返回点的函数中,例如,不必记住在每个返回点上释放互斥 一般的析构函数。也就是说,您为MyClass编写了一次d'tor,然后,如果MyClass实例是MyOtherClass的成员,MyOtherClass不必显式地取消初始化MyClass实例—它的d'tor将自动调用 名称空间 你从C++到C的经历是什么? 对于你最喜欢的C++特征/习语,你找到了哪些替代品?你发现C++有什么特性吗?< /P> < P>观察到的< < LI>除非你计划使用C++编译器来编译C(如果你坚持C++的一个好的子集,你很可能会发现C++中编译器允许的东西,那就是C++中的编译错误)。 没有更多神秘的模板错误(耶!) 没有(语言支持的)面向对象编程

从C++;到C 在C++中编码了几年之后,我在C语言中提供了一个作业编码,在嵌入式领域。 撇开C++在嵌入式领域中的错误与否,是否有一些特点/习语在C++中会被忽略。仅举几个例子: 通用的、类型安全的数据结构(使用模板) 拉伊。尤其是在具有多个返回点的函数中,例如,不必记住在每个返回点上释放互斥 一般的析构函数。也就是说,您为MyClass编写了一次d'tor,然后,如果MyClass实例是MyOtherClass的成员,MyOtherClass不必显式地取消初始化MyClass实例—它的d'tor将自动调用 名称空间 你从C++到C的经历是什么? 对于你最喜欢的C++特征/习语,你找到了哪些替代品?你发现C++有什么特性吗?< /P> < P>观察到的< < LI>除非你计划使用C++编译器来编译C(如果你坚持C++的一个好的子集,你很可能会发现C++中编译器允许的东西,那就是C++中的编译错误)。 没有更多神秘的模板错误(耶!) 没有(语言支持的)面向对象编程,c++,c,C++,C,在一个嵌入式项目上工作时,我试过一次全部使用C语言,但就是受不了。它太冗长了,以至于什么都看不懂。另外,我喜欢我编写的针对嵌入式容器的优化,它必须变成更不安全、更难修复的#define块 C++中的代码看起来像: if(uart[0]->Send(pktQueue.Top(), sizeof(Packet))) pktQueue.Dequeue(1); 变成: if(UART_uchar_SendBlock(uart[0], Queue_Packet_Top(pktQueue)

在一个嵌入式项目上工作时,我试过一次全部使用C语言,但就是受不了。它太冗长了,以至于什么都看不懂。另外,我喜欢我编写的针对嵌入式容器的优化,它必须变成更不安全、更难修复的
#define

C++中的代码看起来像:

if(uart[0]->Send(pktQueue.Top(), sizeof(Packet)))
    pktQueue.Dequeue(1);
变成:

if(UART_uchar_SendBlock(uart[0], Queue_Packet_Top(pktQueue), sizeof(Packet)))
    Queue_Packet_Dequeue(pktQueue, 1);
很多人可能会说这很好,但如果你不得不在一行中进行多个“方法”调用,那就太可笑了。C++的两行将变成C的五(由于80的字符长度限制)。两者都将生成相同的代码,因此不像目标处理器所关心的那样

有一次(1995年),我尝试为多处理器数据处理程序编写大量C语言。每个处理器都有自己的内存和程序的那种。供应商提供的编译器是C编译器(某种HighC衍生工具),它们的库是封闭源代码的,因此我无法使用GCC进行构建,它们的API的设计理念是,您的程序主要是初始化/进程/终止类型,因此处理器间通信充其量只是初级的

<>我在放弃前大约花了一个月,找到了一个副本,并把它存入了MaFiges文件中,这样我就可以使用C++了。CWORD甚至不支持模板,但是C++代码要清楚得多。 通用的、类型安全的数据结构(使用模板)。 C最接近模板的是声明一个头文件,其中包含大量代码,如下所示:

TYPE * Queue_##TYPE##_Top(Queue_##TYPE##* const this)
{ /* ... */ }
然后用类似的方法将其拉入:

#define TYPE Packet
#include "Queue.h"
#undef TYPE
请注意,这不适用于复合类型(例如,没有队列的
无符号字符
),除非您先生成
typedef

哦,记住,如果这个代码实际上没有在任何地方使用,那么你甚至不知道它的语法是否正确

编辑:还有一件事:您需要手动管理代码的实例化。如果你的“模板”代码并不都是内联函数,那么你必须加入一些控件来确保只实例化一次,这样你的链接器就不会抛出一堆“Foo的多个实例”错误

为此,您必须将非内联内容放在头文件的“实现”部分:

#ifdef implementation_##TYPE

/* Non-inlines, "static members", global definitions, etc. go here. */

#endif
然后,在每个模板变体的所有代码中的一个位置,您必须:

#define TYPE Packet
#define implementation_Packet
#include "Queue.h"
#undef TYPE
此外,此实现部分需要在标准的
#ifndef
/
#define
/
#endif
列表之外,因为您可能会在另一个头文件中包含模板头文件,但之后需要在
.c
文件中实例化

是的,它很快就变丑了。这就是为什么大多数C程序员甚至不尝试

拉伊。 尤其是在具有多个返回点的函数中,例如,不必记住在每个返回点上释放互斥

好吧,忘记你漂亮的代码,习惯所有的返回点(函数的结尾除外)

一般的析构函数。 也就是说,您为MyClass编写了一次d'tor,然后,如果MyClass实例是MyOtherClass的成员,MyOtherClass不必显式地取消初始化MyClass实例—它的d'tor将自动调用

对象构造必须以相同的方式显式处理

名称空间。 这实际上是一个很简单的解决方法:在每个符号上加上前缀。这是我前面提到的源代码膨胀的主要原因(因为类是隐式名称空间)。C组的人一直都是这样生活的,好吧,永远都是这样,也许他们看不出有什么大不了的


YMMV

没有比STL更适合C的了。
有一些lib提供类似的功能,但它不再是内置的


我想这是我最大的问题之一。。。我知道用哪个工具可以解决这个问题,但没有使用我必须使用的语言的工具。

< P>我从C++到C,因为一个不同的原因(某种过敏反应),而且只有一些东西我错过了,有些东西我得到了。如果您坚持使用C99,如果可以的话,有一些结构可以让您非常好地、安全地编程,尤其是

  • 指定初始值设定人(最终 与宏相结合)使 将简单类初始化为 无痛构装师
  • 临时变量的复合文本
  • for
    -范围变量可能有助于您执行此操作,特别是确保
    解锁互斥锁或
    释放数组,即使在初始函数返回的情况下也是如此
  • \uuuu VA\u ARGS\uuuu
    宏可用于具有函数的默认参数和执行操作的默认参数
    TYPE * Queue_##TYPE##_Top(Queue_##TYPE##* const this)
    {
        TYPE * result;
        Mutex_Lock(this->lock);
        if(this->head == this->tail)
        {
            result = 0;
            goto Queue_##TYPE##_Top_exit:;
        }
    
        /* Figure out `result` for real, then fall through to... */
    
    Queue_##TYPE##_Top_exit:
        Mutex_Lock(this->lock);
        return result;
    }
    
    uint32_t 
    ScoreList::FindHighScore(
      uint32_t p_PlayerId)
    {
      MutexLock lock(m_Lock); 
    
      uint32_t highScore = 0; 
      for(int i = 0; i < m_Players.Size(); i++)
      {
        Player& player = m_Players[i]; 
        if(player.m_Score > highScore)
          highScore = player.m_Score; 
      }
    
      return highScore; 
    }
    
    uint32_t 
    ScoreList_getHighScore(
      ScoreList* p_ScoreList)
    {
      uint32_t highScore = 0; 
    
      Mutex_Lock(p_ScoreList->m_Lock); 
    
      for(int i = 0; i < Array_GetSize(p_ScoreList->m_Players); i++)
      {
        Player* player = p_ScoreList->m_Players[i]; 
        if(player->m_Score > highScore)
          highScore = player->m_Score; 
      }
    
      Mutex_UnLock(p_ScoreList->m_Lock);
    
      return highScore; 
    }