我有一大块代码,用于获取数组并完成它。在当前项目中,只有一个元素,所以不是将变量更改为char,而是将其声明为char数组[1]。这样我就不需要修改我的代码并冒险添加任何错误,并且如果需求增长,可以轻松增加它。
似乎编译好了,但我对引擎盖下发生的事情感到好奇,我在浪费记忆力吗?这是否会增加额外的处理时间,编译器是否会将其全部优化掉,因此如果我输入它会没有什么不同?
任何人都可以用这种方式解释使用数组的任何可能的缺点。
我使用c和c ++,它们之间有什么不同吗?
答案 0 :(得分:8)
听起来像是一个好策略,没有任何缺点。你绝对不会在C或C ++中浪费内存。大小为1的数组占用的内存与相同类型的变量占用的内存相同。
编译器可能会生成显微效率较低的代码,但这确实不值得担心。
答案 1 :(得分:7)
标准规定,您可以获取不是数组的对象的地址,并将其视为大小为1的数组(因此您可以指向过去的结尾)。
参见C ++ 11标准的第5.7.4节:
出于这些运算符的目的,指向非阵列对象的指针 行为与指向数组的第一个元素的指针相同 长度为1,对象的类型为元素类型。
答案 2 :(得分:3)
首先,您的代码有效,但如果您关心缺点,我可以看到下面列出的问题:
使用数组,当您循环遍历数组时,可以增加使用超出边界访问权限的机会,而不必小心。
另一个缺点是数组不与多态相互作用。有时您尝试将派生对象存储到基类型数组中,对象将被切片,您可能不会注意到。
所以我不会写数组[1]代码。希望这能回答你的一些问题。
答案 3 :(得分:0)
这里我们面对2块代码。
构建代码。
大块代码应该是一个可能分为几个子功能的函数。 另一段代码将调用此函数。
函数的参数。数组或单个字符。
(a) void work( char c );
(b) void work( char& c );
(c) void work( const char v[], size_t size);
(d) void work( char v[], size_t size);
如果工作类型对数组没有意义,则应使用选项(a)和(b)。事实并非如此 如果工作对数组有意义,则应使用选项(c)和(d)。
所以使用数组。
保存数据的变量。数组或单个字符。
如果您只需要持有一个char,那么使用一个非数组char。你仍然可以调用数组函数。
char c;
c = 'b';
work( &c, 1 );
//////
char a[1];
a[0] = 'b';
work( a, 1 );
工作函数将单个变量和数组视为大小为1的数组。在两种情况下,代码都可以正常工作,并且没有效率问题。
<强>测试强>
让我们看看真实的代码是否包含我之前的陈述。
#include <iostream>
#include <ctime>
#include <vector>
#include <cstddef>
#include <chrono>
using namespace std;
unsigned long miliTime()
{
return std::chrono::system_clock::now().time_since_epoch() /
std::chrono::milliseconds(1);
}
// An hypotetical work function with arrays
void workArray( char v[], size_t size )
{
for ( size_t n=0; n<size; ++n )
{
// large block of code
for ( int i=0; i<1000; ++i )
{
v[n] += 3 + i;
if (v[n] == '3' )
v[n] = 'J' - v[n];
v[n] = toupper( v[n] ) + '-';
}
}
}
// Same function just for a single character
void workSingle( char& c )
{
// large block of code
for ( int i=0; i<1000; ++i )
{
c += 3 + i;
if (c == '3' )
c = 'J' - c;
c = toupper( c ) + '-';
}
}
int main(void)
{
const long int repeats =1000000;
long int n;
unsigned long start;
double dif;
start = miliTime();
char c;
c = 'b';
for ( n=0; n<repeats; ++n)
workArray( &c, 1 );
dif = miliTime() - start;
cout << "Result = " << c << endl;
cout << "Non-array var passed to array code = " << dif << " ms" << endl;
start = miliTime();
char a[1];
a[0] = 'b';
for ( n=0; n<repeats; ++n)
workArray( a, 1 );
dif = miliTime() - start;
cout << "Result = " << a[0] << endl;
cout << "Array var passed to array code = " << dif << "ms" << endl;
start = miliTime();
char c2;
c2 = 'b';
for ( n=0; n<repeats; ++n)
workSingle( c2 );
dif = miliTime() - start;
cout << "Result = " << c2 << endl;
cout << "Non-array var passed to non-array code = " << dif << "ms" << endl;
start = miliTime();
char a2[1];
a2[0] = 'b';
for ( n=0; n<repeats; ++n)
workSingle( a2[0] );
dif = miliTime() - start;
cout << "Result = " << a2[0] << endl;
cout << "Array var passed to non-array code = " << dif << "ms" << endl;
}
使用此命令行在gcc-4.7下编译并在我的计算机中执行时:
g++ -O2 -Wall -std=c++11 x.cpp -o x.out && ./x.out
我得到这个输出:
结果= z
传递给数组代码的非数组var = 5520 ms
结果= z
数组var传递给数组代码= 5515ms
结果= z
传递给非数组代码的非数组var = 5203ms
结果= z
数组var传递给非数组代码= 5203ms
正如所料,结果总是一样的。
将数组或非数组变量传递给两个实现的工作函数没有显着差异。
workSingle比workArray快6%。
由于内循环执行1000次,因此外循环(在workSingle中不存在)的执行不太可能是原因。原因可能是由于间接导致访问v [n]比访问c更慢
虽然如果你改变内部循环中的1000来读取从std :: cin读取的全局变量,那么workSingle实际上比workArray提供更慢的时间!
某种优化,缓存未命中或其他低级别的东西可能是原因。我不会牺牲workArray的可重用性,因为工作效率不确定,除非时间非常重要,否则你愿意去装配级别。
<强>结论强>
将变量声明为非数组,因为它只需要保存一个字符 将大部分代码实现为带有数组参数的函数。如果它如此之大,可能会划分为几个小节。