代码之家  ›  专栏  ›  技术社区  ›  Alok Save

在C中可以做什么而不是C++?[关闭]

c c++
  •  10
  • Alok Save  · 技术社区  · 16 年前

    什么是可以在C中做的事情,但不是在C++中,在C++中编码时,这些特征中哪一个最省略?

    我能想到的很少:

    1. 我们可以将任何类型的指针分配给空指针,而不是在C中抛出,而不是在C++中。
    2. 声明变量名称,它们是C++中的关键字,而不是C;

    编辑:感谢@sbi指出:
    1。应该是:我们可以将空指针分配给C中的任何类型的指针,而不是C++中的

    13 回复  |  直到 14 年前
        1
  •  37
  •   Community Mohan Dere    9 年前

    std::vector

    answer with a simple proof-of-concept of a C++ VLA-like class

    void * T *

    interface final synchronized

    • double sin(double x);
    • float sinf(float x);
    • long double sinl(long double x);

    http://www.opengroup.org/onlinepubs/009695399/functions/sin.html

    <tgmath.h>

    awesome

    #define sin(x) __tgmath(x,,,     \
    float, sinf, long double, sinl,  \
    /* etc. */                       \
    , , sin)(x)
    

    http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1340.htm

    • double sin (double x );
    • float sin (float x );
    • long double sin (long double x );

    • auto
    • constexpr
    • nullptr

        3
  •  15
  •   Christoffer    16 年前

        4
  •  4
  •   sbi    16 年前

    void*

        5
  •  3
  •   AnT stands with Russia    16 年前

    void *

    ()

    void foo(int, int);
    void bar(double);
    
    int main() {
      void (*pf)();
    
      pf = foo;
      pf(1, 2); /* valid call */
    
      pf = bar;
      pf(5.0);  /* valid call */
    }
    

    \0

    char str[2] = "ab"; /* valid C, not valid C++ */
    

    int foo() {
    }
    

    foo(); /* fine in C, undefined behavior in C++ */
    

        6
  •  2
  •   Naveen    16 年前
        7
  •  2
  •   Chris    16 年前

        8
  •  2
  •   R. Martinho Fernandes    14 年前

    void* void_ptr;
    int* int_ptr;
    
    int_ptr = void_ptr;  // Invalid in C++, but not in C
    void_ptr = int_ptr;  // Valid in C and C++
    void_ptr = (void*)int_ptr; // Valid in C and C++
    int_ptr = (int*)void_ptr;  // Valid in C and C++
    
        9
  •  1
  •   cHao    16 年前

    a = b;

        10
  •  0
  •   Amir Zadeh    16 年前

    作为C的粉丝,我认为在编码风格的概念中可能还有另外一点,那就是功能性编程,而不是面向对象的编程,即OOP!对于那些将代码作为状态机编写的人来说,这是一个非常有趣的概念!把OpenGL作为一个很好的例子。而且,由于内存引用较少,在C语言中运行代码的速度也非常快。您可能还喜欢听到许多程序员喜欢用C编写代码,因为设计简单,而且他们是如何使用C编写代码的(语法上可能不那么容易)。哦,当你想写接近硬件级别的代码时,你应该使用纯C。

        11
  •  0
  •   paercebal    16 年前

    C99的缺失特征之一是VLA,对于C++来说,它不具有等价性。

    有些人甚至质疑在C++中编写类似VLA的对象的可能性。

    这就是为什么我添加了这个答案:尽管略微偏离主题,但它仍然表明,使用正确的库,C++开发人员仍然可以访问模仿C99特征的对象。因此,这些特征并没有像人们想象的那样被忽略。

    主要代码是:

    #include <iostream>
    #include <string>
    #include "MyVLA.hpp"
    
    template <typename T>
    void outputVLA(const std::string & p_name, const MyVLA<T> & p_vla)
    {
        std::cout << p_name << "\n   MyVla.size() : ["
                  << p_vla.size() << "]\n" ;
    
        for(size_t i = 0, iMax = p_vla.size(); i < iMax; ++i)
        {
            std::cout << "   [" << i << "] : [" << p_vla[i] << "]\n" ;
        }
    }
    
    int main()
    {
        {
            MY_VLA(vlaInt, 5, int) ;
    
            outputVLA("vlaInt: Before", vlaInt) ;
    
            vlaInt[0] = 42 ;
            vlaInt[1] = 23 ;
            vlaInt[2] = 199 ;
            vlaInt[3] = vlaInt[1] ;
            vlaInt[4] = 789 ;
    
            outputVLA("vlaInt: After", vlaInt) ;
        }
    
        {
            MY_VLA(vlaString, 4, std::string) ;
    
            outputVLA("vlaString: Before", vlaString) ;
    
            vlaString[0] = "Hello World" ;
            vlaString[1] = "Wazaabee" ;
            vlaString[2] = vlaString[1] ;
            vlaString[3] = "Guess Who ?" ;
    
            outputVLA("vlaString: After", vlaString) ;
        }
    }
    

    如您所见,myvla对象知道它的大小(这比使用 sizeof C99 VLA上的操作员)。

    当然,myvla类的行为就像一个数组,由一个大小值初始化(在运行时可以更改)。唯一的故障是由于函数的性质 alloca() ,表示只能通过宏my_vla间接使用构造函数:

    下面是文件myvla.hpp中类的代码

    #include <alloca.h>
    
    template <typename T>
    class MyVLA
    {
        public :
            MyVLA(T * p_pointer, size_t p_size) ;
            ~MyVLA() ;
    
            size_t          size()                          const ;
            const T &       operator[] (size_t p_index)     const ;
            T &             operator[] (size_t p_index) ;
    
        private :
            T * m_begin ;
            T * m_end ;
    } ;
    
    #define MY_VLA(m_name, m_size, m_type)                                                      \
    m_type * m_name_private_pointer = static_cast<m_type *>(alloca(m_size * sizeof(m_type))) ;  \
    MyVLA<m_type> m_name(m_name_private_pointer, m_size)
    
    template <typename T>
    inline MyVLA<T>::MyVLA(T * p_pointer, size_t p_size)
    {
        m_begin = p_pointer ;
        m_end = m_begin + p_size ;
    
        for(T * p = m_begin; p < m_end; ++p)
        {
            new(p) T() ;
        }
    }
    
    template <typename T>
    inline MyVLA<T>::~MyVLA()
    {
        for(T * p = m_begin; p < m_end; ++p)
        {
            p->~T() ;
        }
    }
    
    template <typename T>
    inline size_t MyVLA<T>::size() const
    {
        return (m_end - m_begin) ;
    }
    
    template <typename T>
    inline const T & MyVLA<T>::operator[] (size_t p_index) const
    {
        return *(m_begin + p_index) ;
    }
    
    template <typename T>
    inline T & MyVLA<T>::operator[] (size_t p_index)
    {
        return *(m_begin + p_index) ;
    }
    

    宏是一团乱麻,可能写得更好。类本身可能不是异常安全的,但可以这样做。无论如何,它需要更多的代码才能使用(即处理复制/分配、将新的/删除设为私有、添加 const 如有可能,等等)。我的猜测是,结局并不能证明我花在这上面的时间是正当的。所以它仍然是概念的证明。

    点是“C++可以效仿C99 VLAS,它甚至可以作为C++对象数组工作!”我想我已经成功地证明了这一点。

        12
  •  -1
  •   Xolve    16 年前

        13
  •  -2
  •   ifixthat    16 年前