我是C和C ++的新手,并且我至少在C ++中读到,在使用向量和数组时,尤其是在将它们传递到函数中时,最好使用std :: array或std :: vector。 / p>
在我的研究中,我发现以下几点很有意义。我想使用std :: vector可以解决在变量范围之外建立索引的问题。
void foo(int arr[10]) { arr[9] = 0; } void bar() { int data[] = {1, 2}; foo(data); }
上面的代码是错误的,但是编译器认为一切都很好并且 不会发出有关缓冲区溢出的警告。
请使用具有一致值的std :: array或std :: vector 语义并缺乏任何会产生诸如以下错误的“特殊”行为 以上。
(来自bames53的答复,谢谢!)
我要编码的是
float foo(int X, int Y, int l){
// X and Y are arrays of length l
float z[l];
for (int i = 0; i < l; i ++){
z[i] = X[i]+Y[i];
}
return z;
}
int bar(){
int l = 100;
int X[l];
int Y[l];
float z[l];
z = foo(X,Y,l);
return 0;
}
我希望将此代码用C编码,所以我的问题是C是否有std :: vector构造?我找不到任何东西。
预先感谢,也请原谅我的编码(我在C和C ++中像草一般)
答案 0 :(得分:5)
标准C没有像std::vector
或其他容器结构那样的东西。您所获得的只是内置数组和malloc
。
我想使用std :: vector可以解决在变量范围之外建立索引的问题。
您可能会这样认为,但是您会错的:在std::vector
边界之外建立索引与内置数组一样糟糕。 operator[]
的{{1}}也不做任何边界检查(或至少不能保证)。如果要检查索引操作,则需要使用std::vector
而不是arr.at(i)
。
还要注意类似的代码
arr[i]
是错误的,因为在C(或C ++)中没有数组值。当您尝试获取数组的值时,实际上会获得指向其第一个元素的指针。但是当函数返回时,第一个元素(以及所有其他元素和整个数组)将被破坏,因此这是一个经典的无用后错误:调用者获得了一个悬空指针,该指针指向不再存在的对象。
惯用的C解决方案是让调用者处理内存分配,并传递函数刚刚写入的输出参数:
float z[l];
...
return z;
也就是说,有一些库为C提供了动态数据结构,但是它们的外观和感觉与C ++和void foo(float *z, const int *X, const int *Y, int l){
// X and Y are arrays of length l
for (int i = 0; i < l; i ++){
z[i] = X[i]+Y[i];
}
}
有很大不同(例如,我对GLib有所了解)。
答案 1 :(得分:0)
您的问题可能对某些语言的程序员很敏感。 由于不同的语言具有不同的设计决策,因此可以考虑将一种语言的结构转换为另一种语言。
C ++和C占有很大一部分,以某种方式C代码可以(无需大量修改)被编译为C ++。但是,如果您学习精通C ++,您将意识到,由于C的工作原理,会发生很多奇怪的事情。
回到重点:C ++包含一个标准库,其容器为std::vector
。这些容器利用了C:中没有的几种C ++结构:
这些都不存在于C中,因此,为了具有相似的结构,需要几种适应才能获得行为几乎相同的数据结构。
根据我的经验,大多数C项目都有自己的通用数据结构版本,通常基于void*
。通常,它看起来类似于:
struct Vector
{
void *data;
long size;
long capacity;
};
Vector *CreateVector()
{
Vector *v = (Vector *)(malloc(sizeof(Vector)));
memset(v, 0, sizeof(Vector));
return v;
}
void DestroyVector(Vector *v)
{
if (v->data)
{
for (long i = 0; i < v->size; ++i)
free(data[i]);
free(v->data);
}
free(v);
}
// ...
或者,您可以混合使用C和C ++。
struct Vector
{
void *cppVector;
};
#ifdef __cplusplus
extern "C" {
#endif
Vector CreateVector()
void DestroyVector(Vector v)
#ifdef __cplusplus
}
#endif
vectorimplementation.cpp
#include "vector.h"
struct CDataFree
{
void operator(void *ptr) { if (ptr) free(ptr); }
};
using CData = std::unique_ptr<void*, CDataFree>;
Vector CreateVector()
{
Vector v;
v.cppVector = static_cast<void*>(std::make_unique<std::vector<CData>>().release());
return v;
}
void DestroyVector(Vector v)
{
auto cppV = static_cast<std::vector<CData>>(v.cppVector);
auto freeAsUniquePtr = std::unique_ptr<std::vector<CData>>(cppV);
}
// ...
答案 2 :(得分:-1)
c中与std::array
最接近的等效项可能是预处理器宏定义,例如
#define ARRAY(type,name,length) \
type name[(length)]