我正在尝试掌握指针,我有这个简单的代码,我需要一些解释。
我需要将一个char数组复制到另一个。在我的主要功能中,我有这段代码:
const int MAX_SIZE = 100;
char x[MAX_SIZE] = "1234565";
char* y = new char[MAX_SIZE];
copyArray(x, y);
std::cout << y;
delete [] y;
现在问题是,这个代码是如何工作的(这很好):
while ((*dest = *source) != '\0')
{
dest += 1;
source += 1;
}
与此不同(最后给出奇怪的字符):
while (*source != '\0')
{
*dest = *source;
dest += 1;
source += 1;
}
看看这两个函数似乎非常相似。 我们正在复制,直到我们在源字符串中找到空终止符,右(第二个函数)?
但它无法正常工作 - 我在复制的数组末尾会得到一些奇怪的字符。但是,第一个功能正常。
void copyArray(const char* source, char* dest);
答案 0 :(得分:1)
(*dest = *source)
是一个评估表达式,就像int i = 1+1;
的1 + 1部分一样,因此,在评估之后,该值可用于其他表达式
不同之处在于,在((*dest = *source) != '\0')
中,* source的值被赋值给* dest,然后整个表达式被计算(表达式具有与*source
相同的值),而*source
指向的值{1}}仅用于评估*source != '\0'
,但在评估该语句时从未分配过。
修改
user0042带来一个真实的观察:通过这样做,以下代码
while ((*dest = *source) != '\0')
{
dest += 1;
source += 1;
}
确保数组的最终char值为'\ 0'
答案 1 :(得分:1)
表格
while ((*dest = *source) != '\0')
{
dest += 1;
source += 1;
}
保证在测试条件之前应用要复制的字符((*dest = *source)
)的分配,如果到达终止'\0'
字符,则评估为false
。
第二个版本不会复制终止'\0'
字符,因为循环在
*dest = *source;
声明已经达成。
答案 2 :(得分:0)
在示例中,您递增x, y
的地址,直到最后一个字符指向Null-terminator,因此您必须声明一个临时变量来保存第一个地址:
char* x = "1234565";
char* y = new char[MAX_SIZE];
// Temporary pointers to hold the first element's address
char* tmp1 = x;
char* tmp2 = y;
while( (*y = *x) != '\0'){
x += 1; // X no longer points to the first element
y += 1; // Y no longer points to the first element
}
std::cout << tmp2;
您可以使用do while
循环代替while
:
char* x = "1234565";
const int size = strlen(x);
char* y = new char[size];
char* tmp1 = x;
char* tmp2 = y;
do{
*y = *x;
x += 1;
y += 1;
}while( *(x - 1) != '\0');
// Now no need for adding a null-terminator it is already added in the loop
// tmp2[size] = '\0';
std::cout << tmp2;
因为在递增之前分配值,所以最后一个字符\0
将在添加到目标指针y
之前中断循环。因此,我不在n = '\0'
而是在n - 1 = '\0'
上进行循环中断,以确保将其添加到y
。