简体   繁体   English

试图了解C ++中的指针

[英]Trying to understand pointers in C++

I am trying to learn C++ on my own using the "Teach Yourself C++ in 24 hours" by Jesse Liberty. 我正在尝试使用Jesse Liberty的“ 24小时内自学C ++”自己学习C ++。 I wrote this short program to figure out pointers in C++. 我写了这个简短的程序来找出C ++中的指针。

#include <iostream>

void hMany(int count); // hMany function prototype


void hMany(int count){

    do {
        std::cout << "Hello...\n";
        count--;

        }  while (count >0 );

};


int main (int argc, const char * argv[]) {


    int counter;
    int * pCounter = &counter;

    std::cout << "How many hellos? ";
    std::cin >> counter;

    hMany(*pCounter);

    std::cout << "counter is: " << counter << std::endl;
    std::cout << "*pCounter is: " << *pCounter << std::endl;

    return 0;
}

The resulting output is: 结果输出为:

How many hellos? 2
Hello...
Hello...
counter is: 2
*pCounter is: 2

What is the benefit of passing the pointers (*pCounter) vs the argument (counter)? 传递指针(* pCounter)与传递参数(counter)有什么好处?

Any help would be greatly appreciated. 任何帮助将不胜感激。 Luis 路易斯

Update: 更新:

Ok. 好。 The program is working and I now fully understand the C++ pointers. 该程序正在运行,我现在完全了解C ++指针。 Thank you all for your responses. 谢谢大家的答复。 After trying Chowlett's code I was getting 2 warnings (not errors). 尝试了Chowlett的代码后,我得到了2条警告(不是错误)。 One was ! 一个是! No previous prototype for function hMany and *pCount-- ! 没有函数hMany和* pCount--的原型! Expression result unused. 表达式结果未使用。 I was able to correct the prototype on my own but I couldn't figure out the *pCount-- warning. 我能够自行纠正原型,但无法弄清楚* pCount--警告。

I asked my friend Tony for help and here is his answer. 我向我的朋友托尼求助,这是他的答案。

The parentheses make things happen in the correct order. 括号使事情按正确的顺序发生。

(*pCount)--

says to follow the pointer to the integer it points to, and then decrement the integer, which is what you want to do. 表示跟随指针指向它所指向的整数,然后递减该整数,这就是您要执行的操作。

*pCount--

ends up doing the wrong thing, the compiler treats it as 最终做错了事,编译器将其视为

*(pCount—)

which says to decrement the pointer first, leaving it pointing to the “integer” before the one you want to change (there is no such thing since you only have one integer you called this function with), then follow this decremented pointer and do nothing with the integer at that memory location. 它说要先递减指针,然后将其指向要更改的指针之前的“整数”(没有这样的事情,因为只有一个整数调用了此函数),然后跟随此递减的指针而不执行任何操作在该内存位置带有整数。 This is why the compiler complained that the expression result was unused. 这就是为什么编译器抱怨表达式结果未使用的原因。 The compiler was correct. 编译器是正确的。 This code decrements the pointer incorrectly, fetches the wrong integer, and doesn't store that wrong integer anywhere. 此代码会错误地递减指针,获取错误的整数,并且不会在任何地方存储该错误的整数。

Here's the correct code for those new to C++ who might be interested. 对于那些对C ++陌生的人来说,这是正确的代码。

include 包括

void hMany(int *pCount); 无效hMany(int * pCount); // hMany function prototype // hMany函数原型

void hMany(int *pCount){ // *pCount receiving the address of count void hMany(int * pCount){// * pCount接收计数地址

do {
    std::cout << "Hello...\n";


    // The parentheses make things happen in the correct order.
    // says to follow the pointer to the integer it points to, 
    // and then decrement the integer.

          (*pCount)--; 

}  while (*pCount >0 );

} }

int main (int argc, const char * argv[]) { int main(int argc,const char * argv []){

int counter;
int * pCounter = &counter;

std::cout << "How many hellos? ";
std::cin >> counter;

hMany(pCounter); // passing the address of counter

std::cout << "counter is: " << counter << std::endl;
std::cout << "*pCounter is: " << *pCounter << std::endl;

return 0;

} }

int counter;
int * pCounter = &counter;

...

hMany(*pCounter); // Pass by value

hMany(counter);   // Pass by value

What is the benefit of passing the point (*pCounter) vs the argument (counter)? 传递点(* pCounter)与传递参数(counter)有什么好处?

In this case nothing, it's just an educational example. 在这种情况下,什么都没有,仅是一个教育示例。 It shows you can dereference a pointer and get its value by * . 它显示您可以取消引用指针并通过*获得其值。

In addition, both cases are passing by value. 此外,这两种情况都是按价值传递的。

In practice you should avoid using pointers by default, unless you have a good reason. 在实践中,除非有充分的理由,否则应避免默认使用指针。

There is no difference between using *pCounter and counter . 使用*pCountercounter没有什么区别。 In both cases, you are passing the value of the variable counter . 在这两种情况下,您都将传递变量counter However, if you actually pass the pointer itself, you get different behaviour. 但是,如果您实际上传递了指针本身,则会得到不同的行为。

Consider the slightly different program: 考虑稍微不同的程序:

#include <iostream>

void hMany(int* pCount); // hMany function prototype


void hMany(int* pCount){

    do {
        std::cout << "Hello...\n";
        --*pCount;

        }  while (*pCount >0 );

}


int main (int argc, const char * argv[]) {


    int counter;
    int * pCounter = &counter;

    std::cout << "How many hellos? ";
    std::cin >> counter;

    hMany(pCounter);

    std::cout << "counter is: " << counter << std::endl;
    std::cout << "*pCounter is: " << *pCounter << std::endl;

    return 0;
}

In this case, your output will be: 在这种情况下,您的输出将是:

How many hellos? 2
Hello...
Hello...
counter is: 0
*pCounter is: 0

By passing in the pointer to counter (literally, the address in memory of counter ), you allow the function to change counter through its memory location. 通过将指针传递到counter (字面上是counter内存中的地址),您可以允许函数通过其存储位置来更改counter

What is the benefit of passing the point (*pCounter) vs the argument (counter)? 传递点(* pCounter)与传递参数(counter)有什么好处?

There's no "benefit" , this is how you are supposed to pass the value pointed by the pointer pCounter . 没有“好处” ,这就是您应该传递指针pCounter指向的值的方式。

hMany(*pCounter) -> dereferences pCounter to get value hMany(*pCounter) ->取消引用pCounter以获取值

The difference is the scope of the variable. 不同之处在于变量的范围。

If you pass the variable it is copied to the stack in the local scope of the function. 如果传递变量,它将在函数的本地范围内复制到堆栈中。 Changing the value is than done in local copy for the function called, if this is the case 1st your using space if the large variable is passed, 2nd you need to return the value from your function (as the stack will be destroyed once you go back) 更改该值的操作将在本地复制中完成,如果是这种情况,则第一,如果传递了大变量,则使用空间;第二,您需要从函数中返回该值(因为一旦执行该操作,堆栈将被破坏背部)

You can think of it like this: 您可以这样想:

stack: 堆:

current function stack: 当前函数堆栈:

[    ]
[    ]
[    ]
[    ]

when you call another 1 element is added 当您调用另一个1元素时

[    ]
[    ]
[    ]
[    ]
[newel]

when you leave the function it is deleted so its like this again 当您离开该功能时,它将被删除,因此再次像这样

[    ]
[    ]
[    ]
[    ]

newelement value cant be trusted no more. 新元素的价值不再受信任。

But if this is the copy of the pointer, you change not the pointer copy value but the value of the place it points too so the stack will be like this 但是,如果这是指针的副本,则不要更改指针副本的值,而是要更改指针所指向的位置的值,因此堆栈将像这样

[    ]
[ actual_value]
[    ]
[ pointer_to_value]

than you call the function 比您调用该函数

[    ]
[ actual_value]
[    ]
[ pointer_to_value]
[ pointer_to_value_copy]

which will change the actual_value on the stack and quit deleting copy of pointer_to_value 这将更改堆栈上的actual_value,并退出删除pointer_to_value的副本

[    ]
[ actual_value**changed]
[    ]
[ pointer_to_value]

Pointer actually contains memory address with type information of the value that the memory address represents. 指针实际上包含具有该内存地址表示的值的类型信息的内存地址。 It may be used to pass the entity in memory address without instantiating it again to change its value or something like that. 它可以用于在内存地址中传递实体,而无需再次实例化它来更改其值或类似的值。

But in your program, I can't see any benefit from using pointer because a C++ function, hMany in your case, internally re-instantiate the type of value in its argument, `int count' in your case. 但是在您的程序中,使用指针不会带来任何好处,因为在您的情况下,一个c ++函数hMany在内部重新实例化了其参数中的值类型,在您的情况下为'int count'。

As the other answers pointed out, you need to pass pointer of count to the function instead. 正如其他答案指出的那样,您需要将count指针传递给该函数。 In that case, the C++ function will similarly re-instantiate the type of value in its argument, but since the type is pointer, the program will have correct memory address of count inside of the C++ function and can correctly change the value of right identity. 在那种情况下,C ++函数将在其参数中重新实例化值的类型,但是由于类型是指针,因此程序将在C ++函数内部具有正确的count内存地址,并且可以正确更改正确标识的值。

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

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