C++ 将指针传递给函数 (Howto) + C++ 指针操作

Posted

技术标签:

【中文标题】C++ 将指针传递给函数 (Howto) + C++ 指针操作【英文标题】:C++ Passing Pointer to Function (Howto) + C++ Pointer Manipulation 【发布时间】:2011-04-17 07:22:11 【问题描述】:

我对传递指针的工作原理有点困惑。

假设我有以下函数和指针,并且...

编辑

...我想在函数中使用指向某个对象的指针作为参数。

即:

void Fun(int Pointer)
    int Fun_Ptr = ---Passed Pointer---; 
    //So that Fun_Ptr points to whatever ---Passed Pointer points to

在 *Pointer 和 &Pointer 符号之间,我很困惑。我知道 *Pointer 意味着给出它所指向的任何东西。

我是否将 void (int *pointer) 放入声明中。那我用这个功能的时候呢?

感谢您的帮助。

编辑 2:

好的,我现在明白在声明中使用 *variable 意味着将传递一个指针。但是,当我使用该功能时呢?

int main()
    int foo;
    int *bar;
    bar = foo;
    Fun(bar);

编辑 3: 好的,如果我错了,请纠正我:

根据上面代码的约定:

bar = &foo 表示:让 bar 指向内存中的 foo

*bar = foo 表示将 bar 指向的值更改为等于 foo 等于的值

如果我有第二个指针(int *oof),那么:

bar = oof 表示:bar 指向 oof 指针

bar = *oof 表示:bar 指向 oof 指向的值,而不是指向 oof 指针本身

*bar = *oof 意思是:把bar指向的值改成oof指向的值

&bar = &oof 意思是:把bar指向的内存地址改成和oof指向的内存地址一样

我有这个权利吗?

编辑 4:非常感谢您的所有帮助(我希望我能接受超过 1 个答案,但我必须选择第一个答案。我不确定社区 wiki 是如何工作的,但我会留下它以这种方式进行编辑(如果您愿意,可以随意将其变成参考指南)。

【问题讨论】:

不过,您的第二次编辑几乎是正确的 “正确吗?”。不。您不希望bar 等于foo,您希望它指向 foo。这是通过地址操作符完成的。 bar = &foo;. bar = foo, 无效,因为 foo 是一个 int 而 bar 是一个指针。正确的代码是“bar = &foo”,因为作为指针,bar 只能存储内存地址而不是 int。很抱歉评论答案。 记住,bar 指向变量 foo,所以如果你改变 foo,因为 bar 只引用 foo,当你下次使用 bar 时,它也会反映这个变化。 将已删除的评论移至质疑本身,所以上面的评论被搁置(抱歉) 【参考方案1】:

定义变量和使用变量时 * 的用法有所不同。

在声明中,

int *myVariable;

表示指向整数数据类型的指针。然而在使用中,

*myVariable = 3;

意味着取消引用指针并使其指向的结构等于3,而不是使指针等于内存地址0x 0003。

所以在你的函数中,你想这样做:

void makePointerEqualSomething(int* pInteger)

    *pInteger = 7;

在函数声明中,* 表示您正在传递一个指针,但在其实际代码体中 * 表示您正在访问指针所指向的内容。

为了消除您的困惑,我将简要介绍与号 (&)

& 表示获取某物的地址,它在计算机内存中的确切位置,所以

 int & myVariable;

在声明中表示整数或指针的地址!

不过这个

int someData;    
pInteger = &someData;

意味着使 pInteger 指针本身(记住,指针只是它们指向的内存地址)等于“someData”的地址 - 所以现在 pInteger 将指向一些数据,并且可以在您访问它时使用尊重它:

*pInteger += 9000;

这对你有意义吗?还有什么让您感到困惑的地方吗?

@Edit3:

几乎正确,除了三个陈述

bar = *oof;

表示bar指针等于一个整数,而不是bar指向的那个,无效。

&bar = &oof;

& 符号就像一个函数,一旦它返回一个内存地址,你就无法修改它的来源。就像这段代码:

returnThisInt("72") = 86; 

无效,你的也是。

最后,

bar = oof

并不意味着“bar 指向 oof 指针”。相反,这意味着 bar 指向 oof 指向的地址,因此 bar 指向 foo 所指向的任何地址 - 而不是 bar 指向 foo 指向的 oof。

【讨论】:

好的,这是否意味着 pInteger 指针指向 someData 指针? 我应该澄清一下,someData 不是指针,它是一个原始 int。我已经适当地编辑了我的答案。 & 符号现在对你有意义吗? 好吧,我想我有点失望(指针总是让我感到困惑,我真的很努力去理解它们)。我想我现在已经很好地掌握了它。【参考方案2】:

要声明一个带有指向 int 的指针的函数:

void Foo(int *x);

要使用这个功能:


int x = 4;
int *x_ptr = &x;
Foo(x_ptr);
Foo(&x);

如果你想要一个指向另一种类型对象的指针,也差不多:

void Foo(Object *o);

但是,您可能更喜欢使用引用。它们比指针更容易混淆:


// pass a reference
void Foo(int &x)

  x = 2;


//pass a pointer
void Foo_p(int *p)

   *x = 9;


// pass by value
void Bar(int x)

   x = 7;

int x = 4;
Foo(x);  // x now equals 2.
Foo_p(&x); // x now equals 9.
Bar(x);  // x still equals 9.

使用引用,您仍然可以更改传递给函数的 x(就像使用指针一样),但您不必担心取消引用或操作地址。

根据其他人的建议,查看C++FAQLite。这是一个很好的资源。

编辑 3 回复:

bar = &foo 表示:让 bar 指向内存中的 foo

是的。

*bar = foo 表示将 bar 指向的值更改为等于 foo 等于的值

是的。

如果我有第二个指针(int *oof),那么:

bar = oof 表示:bar 指向 oof 指针

bar 将指向任何 oof 指向的内容。它们都会指向同一个东西。

bar = *oof 表示:bar 指向 oof 指向的值,而不是指向 oof 指针本身

没有。你不能这样做(假设 bar 是 int * 类型)你可以制作指针指针。 (int **),但我们不要讨论这个......你不能将指针分配给一个 int(嗯,你可以,但这是一个不符合讨论的细节)。 p>

*bar = *oof 意思是:把bar指向的值改成oof指向的值

是的。

&bar = &oof 意思是:把bar指向的内存地址改成和oof指向的内存地址一样

没有。您不能这样做,因为运算符的地址返回一个右值。基本上,这意味着你不能给它分配东西。

【讨论】:

【参考方案3】:

要传递一个指向 int 的指针,它应该是 void Fun(int* pointer)

传递对 int 的引用看起来像这样...

void Fun(int& ref) 
   ref = 10;


int main() 
   int test = 5;
   cout << test << endl;  // prints 5

   Fun(test);
   cout << test << endl;  // prints 10 because Fun modified the value

   return 1;

【讨论】:

【参考方案4】:

如果你想将一个指向 int 的指针传递给你的函数,

功能声明(如果需要):

void Fun(int *ptr);

函数定义:

void Fun(int *ptr) 
    int *other_pointer = ptr;  // other_pointer points to the same thing as ptr
    *other_ptr = 3;            // manipulate the thing they both point to

函数的使用:

int main() 
    int x = 2;
    printf("%d\n", x);
    Fun(&x);
    printf("%d\n", x);

请注意,作为一般规则,名为PtrPointer 的变量永远不应具有int 类型,这就是您在代码中的类型。指向 int 的指针的类型为 int *

如果我有第二个指针(int *oof), 那么:

bar = oof 表示:bar 指向 oof 指针

意思是“让 bar 指向 oof 指向的东西”。

bar = *oof 表示:bar 指向 oof 指向但不指向的值 oof 指针本身

这没有任何意义,它是无效的。 bar 是一个指针 *oof 是一个 int。您不能将一个分配给另一个。

*bar = *oof 表示:将 bar 指向的值更改为 oof 指向

是的。

&bar = &oof 表示:改变内存 栏指向的地址相同 作为 oof 指向的内存地址 到

不,这又是无效的。 &amp;bar 是一个指向 bar 变量的指针,但它是所谓的“右值”或“临时”,它不能被赋值。这就像算术计算的结果。你不能写x + 1 = 5

将指针视为地址可能会对您有所帮助。 bar = oof 表示“make bar,是地址,等于oof,也是地址”。 bar = &amp;foo 表示“make bar,是一个地址,等于 foo 的地址”。如果bar = *oof 有任何含义,则表示“make bar,它是一个地址,等于*oof,它是一个int”。你不能。

那么,&amp; 是地址运算符。它的意思是“操作数的地址”,所以&amp;foo 是 foo 的地址(即指向 foo 的指针)。 * 是取消引用运算符。它的意思是“操作数给出的地址处的东西”。所以完成了bar = &amp;foo*barfoo

【讨论】:

【参考方案5】:
void Fun(int *Pointer)

  //if you want to manipulate the content of the pointer:
  *Pointer=10;
  //Here we are changing the contents of Pointer to 10

* 在指针前表示指针的内容(声明中除外!)

&在指针(或任何变量)之前表示地址

编辑:

int someint=15;
//to call the function
Fun(&someint);
//or we can also do
int *ptr;
ptr=&someint;
Fun(ptr);

【讨论】:

@tommieb75:为什么它是有效的 C 很重要?这也是 C++ 语法,发问者没有指定“C++,删除了 C”。不管那是什么。【参考方案6】:
void Fun(int* Pointer)   -- would be called as Fun( &somevariable )

将允许您通过在 Fun 函数中取消引用来操纵“指针”指向的内容,即

*Pointer = 1;

如上声明它还允许您操作超出其指向的数据:

int foo[10] = 0;
Fun(foo);

在函数中你可以像 *(Pointer + 1) = 12;设置数组的第二个值。

void Fun(int& Pointer)  -- would be called Fun( somevariable )

您可以修改 Pointer 引用的内容,但在这种情况下,您无法访问 Pointer 引用的内容之外的任何内容。

【讨论】:

【参考方案7】:

使用更简洁、更强大的 Functionoid 可能会让您更容易理解,请参阅此优秀且强烈推荐的 C++ FAQ lite,尤其是从第 33.12 节开始,但尽管如此,请从头开始阅读了解该部分的内容。

回答你的问题:

typedef void (*foobar)() fubarfn;

void Fun(fubarfn& baz)
   fubarfn = baz;
   baz();

编辑:

&amp; 表示参考地址 * 表示引用地址中包含的值,称为去引用

所以使用引用,下面的例子,说明我们是传入一个参数,直接修改它。

void FunByRef(int& iPtr)
    iPtr = 2;


int main(void)
    // ...
    int n;
    FunByRef(n);
    cout << n << endl; // n will have value of 2

【讨论】:

也许我应该澄清一下。我不是试图使用指向函数的指针,而是将指向某个对象(比如 int)的指针传递给函数,以便函数可以对其进行操作。我将修改我的问题以澄清这一点。

以上是关于C++ 将指针传递给函数 (Howto) + C++ 指针操作的主要内容,如果未能解决你的问题,请参考以下文章

将指针数组传递给函数指针数组的 C++ 问题

工厂:如何将临时智能指针传递给函数。 C++

将二维数组指针传递给c ++中的函数[重复]

c ++分段错误将指针传递给函数

将指针向量传递给c ++中的函数[重复]

C ++将向量传递给函数:引用与指针,哪个是首选? [复制]