我对指针有疑问。当我在函数中使用指向char数组的指针遍历char数组时,原始数组保持不变,但是当我在main函数中执行它时,我无法打印char数组。
我是指点新手。
void f(char* a)
{
while (*a!=0) {
*(a++); // going through array
}
}
int main()
{
char* a1 = "test";
f(a1);
cout <<a1<<endl; // I can normally print out "test"
return 0;
}
但是,
int main()
{
char* a1 = "test";
while (*a1!=0) {
*(a1++);
}
cout <<a1<<endl; // won't print anything
return 0;
}
所以我的问题是,即使我将指针传递给函数,为什么原始数组没有被修改?
答案 0 :(得分:5)
由于您正在递增指针a1
,因此它指向main
中循环结尾处的字符'\ 0'。打印空字符不会打印任何内容(空字符串)。
使用函数执行此操作时,指针a
是本地的,是函数的本地。它在函数内被修改但在main
中没有改变。如果您希望两个示例之间有类似的结果,则必须更改函数以接受指针的引用参数:
void f(char * &a) { . . . }
答案 1 :(得分:3)
f(a1);
a1
退出后,不会修改您的f
然而
while (*a1!=0) {
*(a1++);
}
之前cout
会使a1
指向空字符,因此不会打印任何内容
答案 2 :(得分:3)
调用函数时,您不会更改a1
。您只是更改了传递给该函数的a1
副本:a
但是当您在主要功能中拨打a1++
时,您正在更改a1
,当它完成时,a1
将为0
或'\0'
答案 3 :(得分:2)
不同之处在于,在第二种情况下,a1
在循环存在后指向\0
个字符。要在1的情况下看到相同的结果,请通过引用接收指针。
void f(char* & a); // Valid in C++ only
答案 4 :(得分:2)
当函数main()仍处于活动状态时,数组a1
存在
a1
的地址将传递给该函数
此类地址保留给a1
,因为main()
仍处于有效状态
现在,变量a
是一个指针,其初始值是a1
的副本,在您执行调用时f(a1)
。
考虑到a
是一个变量,其行为类似于int,char,float等。
因此,如果您修改其“值”(即,在这种情况下,a
指向的内存地址),a1
的原始地址保持不变。
但是,如果您修改f()中的a
成员:
a[0] = '!';
然后原始数组变为:a1
等于"!est"
原因是您正在更改a
(加0)地址中保存的字符的内容,这是{在f()
执行的最开始){的地址内容{1}}(加0)。
答案 5 :(得分:1)
详细了解指针here
为了能够在第二种情况下打印字符串,请执行以下操作:
#include <iostream>
using std::cout;
using std::endl;
int main()
{
char* a1 = "test";
char *ptr = a1; //create another pointer to a1
while (*ptr != 0) cout << *ptr++;
cout << endl << a1 << endl;
//You should get an output of the same string on 2 lines
return 0;
}
答案 6 :(得分:1)
a
中的形式参数f
是内存中与a1
中的实际参数main
不同的对象,因此更改a
的值会不影响a1
。
要模仿第二个代码段的行为,您必须将指针传递给a1
,如下所示:
void f( char **a )
{
while ( **a != 0 )
(*a)++; // increment the thing a points to
}
int main( void )
{
char *a1 = "test";
f( &a1 ); // pass a pointer to a1
cout << a1 << endl;
return 0;
}
在此代码中,我们不会将a1
中存储的值传递给f
,而是传递a1
的地址。在f
,我们不会写信给a
,我们会写信给*a
或a
指向的地址。
答案 7 :(得分:0)
您正在使用按值传递。 (C ++中的所有内容都是按值传递,除非函数参数是引用类型,即具有&
,在这种情况下它将通过引用传递。)
在按值传递时,对参数的赋值(以及++
是赋值)对函数外部的事物没有任何影响。