简体   繁体   English

使用指向char的指针打印字符数组

[英]Printing array of chars using pointer to char

I have a question regarding pointers. 我有关于指针的问题。 When I iterate through a char array using pointer to char array in function, original array stays the same, but when I do it in main function, I can't print char array. 当我在函数中使用指向char数组的指针遍历char数组时,原始数组保持不变,但是当我在main函数中执行它时,我无法打印char数组。

I am new to pointers. 我是新手。

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;
}

But, 但,

int main()
{
    char* a1 = "test";
    while (*a1!=0) {
    *(a1++);
    }
    cout <<a1<<endl; // won't print anything
    return 0;
}

So my question is, even though I am passing pointer to function, why is original array not modified? 所以我的问题是,即使我将指针传递给函数,为什么原始数组没有被修改?

Since you're incrementing the pointer a1 , it points to the character '\\0' at the end of the loop in main . 由于你正在递增指针a1 ,它指向main循环末尾的字符'\\ 0'。 Printing a null character prints nothing (empty string). 打印空字符不会打印任何内容(空字符串)。

When you do this with a function, the pointer a is local is local to the function. 使用函数执行此操作时,指针a是本地的是函数的本地。 It is modified within the function but is not changed in main . 它在函数内被修改但在main没有改变。 If you wanted similar results between the two examples, you would have to change the function to accept a reference parameter to the pointer: 如果您希望两个示例之间有类似的结果,则必须更改函数以接受指针的引用参数:

void f(char * &a) { . . . }

f(a1);

won't modify your a1 after f exits f退出后不会修改你的a1

However 然而

while (*a1!=0) {
    *(a1++);
    }

before cout cout之前

will make a1 to point to null character, so nothing gets printed 将使a1指向null字符,因此不会打印任何内容

you're not changing a1 when you call your function. 当你打电话给你的功能时,你不会改变a1 you're only changeing a copy of a1 that is passed into that function: a 你只是改变传递给该函数的a1的副本: a

But when you call a1++ in your main function, you are changing a1 and when it's finished, a1 will be 0 or '\\0' 但是当你在main函数中调用a1++时,你正在改变a1 ,当它完成时, a1将为0'\\0'

The difference is that in second case, a1 is pointing to \\0 character after the loop exists. 不同之处在于,在第二种情况下, a1在循环存在后指向\\0字符。 To see the same result in case of 1, receive pointer by reference. 要在1的情况下看到相同的结果,请通过引用接收指针。

void f(char* & a); // Valid in C++ only

The array a1 exists while the function main() is still active. 当函数main()仍处于活动状态时,数组a1存在。
The address of a1 is passed to the function. a1的地址传递给函数。
Such address is reserved to a1 because main() is still active. 这样的地址保留给a1因为main()仍处于活动状态。
Now, the variable a is a pointer whose initial value is a copy of a1 , in the moment you do the call f(a1) . 现在,变量a是一个指针,其初始值是a1的副本,在您执行调用f(a1)的那一刻。

Take in account that a is a variable, and behaves like int, char, float, etc. So, if you modify its "value" (that is, in this case, the memory address that a points to), the original address of a1 keeps untouched. 就拿帐户,它a是一个变量,其行为如int,char和float等,所以,如果你修改其“价值”(即,在这种情况下,内存地址是a点),原地址a1保持不变。

However, if you modify a member of a inside f(): 但是,如果修改的成员a内部F():

  a[0] = '!';

then the original array becomes: a1 equals to "!est" . 然后原始数组变为: a1等于"!est"
The reason is that you are changing the content of the character held in the address of a (plus 0), which is (at the very start of execution of f() ) the content of the address of a1 (plus 0). 其原因是,你改变的地址举行了品格的a (加0),这是(在执行最开始的f()的地址的内容a1 (加0)。

Read more about pointers here 在这里阅读有关指针的更多信息

To be able to print the string in your second case, do this: 为了能够在第二种情况下打印字符串,请执行以下操作:

#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;
}

The formal parameter a in f is a different object in memory from the actual parameter a1 in main , so changing the value of a does not affect a1 . 形式参数af是在从实际的参数存储器一个不同的对象a1main ,所以改变的值a不影响a1

To mimic the behavior of the second snippet, you would have to pass a pointer to a1 , like so: 要模仿第二个代码段的行为,您必须将指针传递给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;
}

In this code, we don't pass the value stored in a1 to f , we pass the address of a1 . 在这段代码中,我们不将存储在a1的值传递给f ,我们传递a1地址 In f , we don't write to a , we write to *a , or what a points to. f ,我们不写a ,我们写*a ,或者是什么a点。

You are using pass-by-value . 您正在使用按值传递 (Everything in C++ is pass-by-value unless the function parameter is a reference type, ie has & , in which case it would be pass-by-reference.) (除非函数参数是引用类型,否则C ++中的所有内容都是按值传递,即具有& ,在这种情况下,它将通过引用传递。)

In pass-by-value, assignments to a parameter (and ++ is an assignment) do not have any effect on things outside the function. 在pass-by-value中,对参数的赋值(和++是赋值)对函数外部的事物没有任何影响。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM