c/c++语言开发共享将指针/引用传递给函数

这听起来像是一个愚蠢的问题,但我还在学习C,所以请耐心等待。 ?

我正在研究K&R(结构)的第6章,到目前为止,这本书已经取得了巨大的成功。 我决定使用结构非常重要,因此在本章的早期就使用了point和rect示例做了很多工作。 我想尝试的一件事是通过指针改变canonrect函数(第2版,第131页),因此返回void

我有这个工作,但遇到了打嗝,我希望你们可以帮助我。 我希望canonRect创建一个临时矩形对象,执行其更改,然后重新分配它传递给临时矩形的指针,从而简化代码。

但是,如果我这样做,矩形不会改变。 相反,我发现自己手动重新填充我传入的矩形字段,这确实有效。

代码如下:

 #include  #define min(a, b) ((a)  (b) ? (a) : (b)) struct point { int x; int y; }; struct rect { struct point lowerLeft; struct point upperRight; }; // canonicalize coordinates of rectangle void canonRect(struct rect *r); int main(void) { struct point p1, p2; struct rect r; p1.x = 10; p1.y = 10; p2.x = 20; p2.y = 40; r.lowerLeft = p2; // note that I'm inverting my points intentionally r.upperRight = p1; printf("Rectangle, lower left: %d, %d; upper right: %d %dnn", r.lowerLeft.x, r.lowerLeft.y, r.upperRight.x, r.upperRight.y); // can't pass a pointer, only a reference. // (Passing pointers results in illegal indirection compile time errors) canonRect(&r); printf("Rectangle, lower left: %d, %d; upper right: %d %dnn", r.lowerLeft.x, r.lowerLeft.y, r.upperRight.x, r.upperRight.y); } void canonRect(struct rect *r) { struct rect temp; temp.lowerLeft.x = min(r->lowerLeft.x, r->upperRight.x); temp.lowerLeft.y = min(r->lowerLeft.y, r->upperRight.y); temp.upperRight.x = max(r->lowerLeft.x, r->upperRight.x); temp.upperRight.y = max(r->lowerLeft.y, r->upperRight.y); r = &temp; // doesn't work; my passed-in rect remains the same // I wind up doing the following instead, to reassign all // the members of my passed-in rect //r->lowerLeft = temp.lowerLeft; //r->upperRight = temp.upperRight; } 

以下是问题:

我怀疑我已经知道了#1的答案,但#2让我感到困惑 – 我认为传递指针是合法的。

无论如何……请原谅C newb。

    我想你想要做的是:

     void canonRect(struct rect *r) { struct rect temp; temp.lowerLeft.x = min(r->lowerLeft.x, r->upperRight.x); temp.lowerLeft.y = min(r->lowerLeft.y, r->upperRight.y); temp.upperRight.x = max(r->lowerLeft.x, r->upperRight.x); temp.upperRight.y = max(r->lowerLeft.y, r->upperRight.y); *r = temp; } 

    在上面的代码中,您设置* r,其类型为rect,类型为rect。

    Re 1:如果你想改变r指向的东西,你需要使用指向指针的指针。 如果这真的是你想要的(见上文,它不是你想要的那样)那么你必须确保将它指向堆上的东西。 如果你将它指向不是用’new’或malloc创建的东西,那么它将超出范围,你将指向不再用于该变量的内存。

    为什么你的代码不适用于r =&temp?

    因为r是rect *类型。 这意味着r是一个变量,它保存一个内存包含一个rect的内存地址。 如果你改变r指向的东西,那很好,但这不会改变传入的变量。

    Re 2:*未在类型声明中使用时是解引用一元运算符。 这意味着它将查找指针地址内的内容。 所以通过传递* r,你根本就没有传递指针。 因为r不是指针,所以这是无效的语法。

    值得注意的是,只要该方法canonRect结束并且您将指向无效的内存,您的变量’struct rec temp’将超出范围。

    听起来你把“解除引用”运算符( * )与“运算符地址”( & )混淆了。

    当你写&r ,它获取&r的地址并返回一个指向r的指针(指针只是一个变量的内存地址)。 所以你真的将指针传递给函数。

    当你写*r ,你试图取消引用r。 如果r是一个指针,那将返回r指向的值。 但是r不是指针,它是一个矩形,所以你会得到一个错误。

    为了使事情更加混乱,在声明指针变量时也使用*字符。 在这个函数声明中:

     void canonRect(struct rect *r) { 

    r被声明为指向struct rect的指针。 这与使用*完全不同:

     canonRect(*r); 

    在这两种情况下,*字符意味着完全不同的东西。

    首先,K&R c没有“引用”的概念,只是指针。 &运算符意味着“取地址”。


    其次, cannonRect()r是局部变量,而不是 main()r 。 更改本地r点的位置不会影响调用例程中的r


    最后,如前所述,本地struct rect在堆栈上分配,并且在close括号中超出范围,

    您可能希望了解参数可以(概念上)传递给函数的不同方法。 C是按值调用 ,因此当您将指针传递给函数的rect时,您将传递指针的副本。 函数直接(非间接)对值r所做的任何更改都不会对调用者可见。

    如果你希望函数为调用者提供一个新结构,那么有两种方法:1。你可以返回一个矩形:2。你可以将一个指针传递给指向rect的指针:

    第一种方式更自然:

     struct rect* canonRect(struct rect* r) { struct rect* cr = (struct rect*) malloc(sizeof(struct rect)); ... return cr; } 

    第二种方式是:

     void canonRect(struct rect** r) { *r = (struct rect*) malloc(sizeof(struct rect)); } 

    然后调用者将使用:

      canonRect(&r); 

    但是调用者失去了它的原始指针,你必须小心不要泄漏结构。

    无论使用哪种技术,该函数都需要使用malloc为堆上的新结构分配内存。 只能通过声明一个struct来分配堆栈空间,因为当函数返回时该内存变为无效。

    2.如果我尝试传入指向canonRect的指针,为什么会出现非法的间接编译时错误? (IE,如果我有canonRect(* r);在main()中。)

    因为,它不是指针的目的。

    需要了解更多c/c++开发分享将指针/引用传递给函数,也可以关注C/ C++技术分享栏目—计算机技术网(www.ctvol.com)!

      以上就是c/c++开发分享将指针/引用传递给函数相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。

      本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。

      ctvol管理联系方式QQ:251552304

      本文章地址:https://www.ctvol.com/c-cdevelopment/979896.html

      (0)
      上一篇 2021年12月13日
      下一篇 2021年12月13日

      精彩推荐