std::C中的数组等价 我是C和C++的新手,我读过至少在C++中,最好使用STD::数组或STD::vector,当使用向量和数组时,特别是当这些函数传递到函数时。
在我的研究中,我发现以下几点是有道理的。我认为使用std::vector可以解决在变量范围之外建立索引的问题 上面的代码是错误的,但编译器认为一切都很好,并且 不会发出有关缓冲区溢出的警告 而是使用std::array或std::vector,它们具有一致的值 语义和缺少任何产生错误的“特殊”行为,如 以上 (来自bames53的回答,顺便说一句,谢谢!) 我想编码的是std::C中的数组等价 我是C和C++的新手,我读过至少在C++中,最好使用STD::数组或STD::vector,当使用向量和数组时,特别是当这些函数传递到函数时。,c,arrays,vector,C,Arrays,Vector,在我的研究中,我发现以下几点是有道理的。我认为使用std::vector可以解决在变量范围之外建立索引的问题 上面的代码是错误的,但编译器认为一切都很好,并且 不会发出有关缓冲区溢出的警告 而是使用std::array或std::vector,它们具有一致的值 语义和缺少任何产生错误的“特殊”行为,如 以上 (来自bames53的回答,顺便说一句,谢谢!) 我想编码的是 float foo(int X, int Y, int l){ // X and Y are arrays of le
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;
}
float foo(整数X,整数Y,整数l){
//X和Y是长度为l的数组
浮动z[l];
对于(int i=0;i
我想用C来编码,所以我的问题是C是否有std::vector结构?我在那上面找不到任何东西
提前感谢,也请原谅我的编码(我在C和C++中是绿色的)。标准C没有类似于
std::vector
或其他容器结构。您得到的只是内置阵列和malloc
我认为使用std::vector可以解决在变量范围之外建立索引的问题
您可能会这样认为,但您错了:在std::vector
的边界之外建立索引与使用内置数组一样糟糕。std::vector
的操作符[]
也不执行任何边界检查(或者至少不保证执行)。如果要检查索引操作,需要使用arr.at(i)
而不是arr[i]
还要注意的是
float z[l];
...
return z;
是错误的,因为C(或C++)中没有数组值。当您尝试获取数组的值时,实际上会获得指向其第一个元素的指针。但是,当函数返回时,第一个元素(以及所有其他元素和整个数组)将被销毁,因此这是释放bug后的一个经典用法:调用方将获得指向不再存在的对象的悬空指针
惯用的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];
}
}
void foo(浮点*z,常量int*X,常量int*Y,常量l){
//X和Y是长度为l的数组
对于(int i=0;i
< P > >,有一些库为C++提供动态数据结构,但它们必然看起来和感觉与C++和<代码> STD::向量< /代码>(例如我知道)非常不同。 最接近的等价代码<代码>::数组中的< <代码>可能是一个预处理器宏定义,如
#define ARRAY(type,name,length) \
type name[(length)]
您的问题可能对该语言的某些程序员很敏感。 将一种语言的结构用于另一种语言可能被视为诅咒,因为不同的语言有不同的设计决策
C++和C共享了一个很大的部分,C代码可以(不需要很多修改)编译成C++。但是,如果你学习掌握C++,你会发现很多奇怪的事情都是因为C是如何工作的。
回到点:C++包含一个标准容器,容器为<代码> STD::vector < /代码>。这些容器使用了一些C++结构,它们在C:
中不可用。- RAII(当实例超出范围时执行析构函数的事实)将防止分配内存的内存泄漏
- 模板将允许类型安全性不混合双重、浮动、类
- 运算符重载将允许同一函数使用不同的签名(如擦除)
- 成员函数
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);
}
// ...
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);
}
// ...
#包括“vector.h”
结构CDATA免费
{
void运算符(void*ptr){if(ptr)free(ptr);}
};
使用CData=std::unique\u ptr;
向量CreateVector()
{
向量v;
v、 cppVector=静态_cast(std::make_unique().release());
返回v;
}
无效向量(向量v)
{
自动cppV=静态_投射(v.cppVector);
自动freeAsUniquePtr=std::unique_ptr(cppV);
}
// ...
>C是否有std::vector
构造?不,您必须自己实现它或使用一个库来实现它。除了数组和指针之外,C没有容器,C或C++标准不允许在堆栈上基于变量的分配数组。用C++你需要去一些<代码> MARROCKE()/CUT>解决方案,在C++中你会使用<代码> STD::vector < /代码>。有没有理由在C中寻找<代码> STD::向量< /代码>?为什么不使用C++来代替呢?如果你是初学者,你肯定想学习C++,而不是C。如果你有很强的理由,你只应该和C一起。你的代码太过模糊以至于连伪代码也不能理解,你把一个数组传递给<代码> int >代码,然后评论<代码> int >代码>表示大小?无论如何,在标准C.@πάντα中没有std::vector
类似物ῥεῖ 实际上,C99支持可变长度数组(C11中可选)。因此,对于足够小的数组,您不需要malloc
。谢谢!我刚刚编写了这段代码,我意识到您所说的将输出参数传递给函数。我只是改变了它,让Y成为输出。(即Y[i]=X[i]+Y[i])。从对我的问题的回答中,我也应该收集到C++的扩展代码,如果有什么问题的话。
struct Vector
{
void *cppVector;
};
#ifdef __cplusplus
extern "C" {
#endif
Vector CreateVector()
void DestroyVector(Vector v)
#ifdef __cplusplus
}
#endif
#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);
}
// ...