0

我正在尝试使用 Jesse Liberty 的“24 小时内自学 C++”自学 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;
}

结果输出是:

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

传递指针 (*pCounter) 与参数 (counter) 有什么好处?

任何帮助将不胜感激。路易斯

更新:

好的。该程序正在运行,我现在完全理解了 C++ 指针。谢谢大家的回复。在尝试了 Chowlett 的代码后,我收到了 2 个警告(不是错误)。一个是!函数 hMany 和 *pCount-- 没有以前的原型!表达式结果未使用。我能够自己更正原型,但我无法弄清楚 *pCount-- 警告。

我向我的朋友托尼寻求帮助,这是他的回答。

括号使事情以正确的顺序发生。

(*pCount)--

说跟随指向它指向的整数的指针,然后递减整数,这就是你想要做的。

*pCount--

最终做错事,编译器将其视为

*(pCount—)

它说首先递减指针,让它指向你想要改变的那个之前的“整数”(没有这样的事情,因为你只有一个你调用这个函数的整数),然后跟随这个递减的指针并且什么都不做与该内存位置的整数。这就是编译器抱怨表达式结果未使用的原因。编译器是正确的。此代码错误地递减指针,获取错误的整数,并且不会在任何地方存储该错误的整数。

对于那些可能感兴趣的 C++ 新手来说,这是正确的代码。

包括

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

void hMany(int *pCount){ // *pCount 接收 count 的地址

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

}

4

5 回答 5

2

*pCounter使用和没有区别counter。在这两种情况下,您都在传递变量的counter。但是,如果您实际上传递指针本身,您会得到不同的行为。

考虑稍微不同的程序:

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

在这种情况下,您的输出将是:

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

通过传入指向counter(字面意思是 的内存地址)的指针,counter您允许函数counter通过其内存位置进行更改。

于 2013-10-02T13:48:28.780 回答
2
int counter;
int * pCounter = &counter;

...

hMany(*pCounter); // Pass by value

hMany(counter);   // Pass by value

传递点 (*pCounter) 与参数 (counter) 有什么好处?

在这种情况下什么都没有,这只是一个教育例子。它表明您可以取消引用指针并通过*.

此外,这两种情况都是按值传递的。

在实践中,您应该避免默认使用指针,除非您有充分的理由。

于 2013-10-02T13:40:32.557 回答
0

指针实际上包含内存地址和内存地址所代表的值的类型信息。它可用于传递内存地址中的实体,而无需再次实例化它以更改其值或类似的东西。

但是在您的程序中,我看不到使用指针的任何好处,因为hMany在您的情况下,C++ 函数会在内部重新实例化其参数中的值类型,在您的情况下为“int count”。

正如其他答案指出的那样,您需要将计数指针传递给函数。在这种情况下,C++ 函数将类似地在其参数中重新实例化值的类型,但由于类型是指针,因此程序将具有countC++ 函数内部的正确内存地址,并且可以正确更改正确标识的值。

于 2013-10-02T14:32:19.137 回答
0

区别在于变量的范围。

如果您传递变量,它将被复制到函数本地范围内的堆栈中。更改值不是在调用函数的本地副本中完成,如果是这种情况,如果传递了大变量,则第一次使用空间,第二次您需要从函数返回值(因为一旦您去,堆栈将被销毁背部)

你可以这样想:

堆:

当前函数栈:

[    ]
[    ]
[    ]
[    ]

当您调用另一个 1 元素时

[    ]
[    ]
[    ]
[    ]
[newel]

当您离开该功能时,它会被删除,因此再次像这样

[    ]
[    ]
[    ]
[    ]

新元素的价值不能再被信任了。

但是,如果这是指针的副本,您更改的不是指针副本值,而是它指向的位置的值,所以堆栈将是这样的

[    ]
[ actual_value]
[    ]
[ pointer_to_value]

比你调用函数

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

这将更改堆栈上的 actual_value 并退出删除 pointer_to_value 的副本

[    ]
[ actual_value**changed]
[    ]
[ pointer_to_value]
于 2013-10-02T13:45:54.463 回答
0

传递点 (*pCounter) 与参数 (counter) 有什么好处?

没有“好处”,这就是您应该传递指针指向的值的方式pCounter

hMany(*pCounter) -> 取消引用pCounter以获取价值

于 2013-10-02T13:40:24.320 回答