指针是否被认为是在C中通过引用调用的方法?

Ins*_*ane 65 c pointers pass-by-reference

在我大学的C编程课程中,教授及其后来的书在引用C中的指针时使用了术语调用或通过引用传递.

我的教授称之为"参考函数调用"的一个例子:

int sum(int *a, int *b);
Run Code Online (Sandbox Code Playgroud)

我的教授称之为"价值函数呼叫"的一个例子:

int sum(int a, int b);
Run Code Online (Sandbox Code Playgroud)

读过 C不支持通过引用调用.根据我的理解,指针通过值传递.

基本上,说指针是C通过引用传递的方式是不正确的吗?说你不能通过C中的引用传递但是可以使用指针替代它会更正确吗?


2015年11月11日更新

从我的问题起源的方式来看,我认为术语的争论已经产生,实际上我看到了两个具体的区别.

  • pass-by-reference(主要用于今天的术语):C++等语言中使用的特定术语
  • pass-by-reference(我的教授用来解释指针的范例):在C++之类的语言开发之前使用的一般术语,因此在术语被重写之前

在阅读了@Haris的更新答案之后,为什么这不是那么黑白,这是有道理的.

Har*_*ris 56

你不能通过C中的引用传递,但可以使用指针作为替代

是的,那是正确的.


详细说明一点.无论你作为c函数的参数传递什么,它都只通过值传递.无论是变量值还是变量地址.

是什么让你与众不同.

当我们传递值时,我们将变量的值传递给函数.当我们传递引用时,我们将变量的别名传递给函数.C可以将指针传递给函数,但仍然是按值传递.它将指针的值(地址)复制到函数中.


  • 如果要发送变量的值,则该函数仅接收该值,并且更改该值不会影响原始值.

  • 如果要发送变量的地址,那么也只发送值(本例中的地址),但由于您具有变量的地址,因此可以使用它来更改原始值.


作为一个例子,我们可以看到一些C++代码来理解call-by-value和call-by-reference之间的真正区别.取自网站.

// Program to sort two numbers using call by reference. 
// Smallest number is output first.

#include <iostream>
using namespace std;

// Function prototype for call by reference
void swap(float &x, float &y);

int main()
{
   float a, b;

   cout << "Enter 2 numbers: " << endl;
   cin >> a >> b;
   if(a>b) 
     swap(a,b); // This looks just like a call-by-value, but in fact
                // it's a call by reference (because of the "&" in the
                // function prototype

   // Variable a contains value of smallest number
   cout << "Sorted numbers: ";
   cout << a << " " << b << endl;
   return 0;
}

// A function definition for call by reference
// The variables x and y will have their values changed.

void swap(float &x, float &y)
// Swaps x and y data of calling function
{
   float temp;

   temp = x;
   x = y;
   y = temp;
}
Run Code Online (Sandbox Code Playgroud)

在这个C++示例中,正在使用引用变量(在C中不存在).引用这个网站,

"引用是别名,或现有变量的替代名称......",

"引用的主要用途是作为函数形式参数来支持传递引用......"

这与使用指针作为函数参数不同,因为,

"指针变量(或简称指针)基本上与其他变量相同,后者可以存储一段数据.与存储值的常规变量(如int,double,char)不同,指针存储一个记忆地址."

因此,基本上当一个人发送地址并通过指针接收时,一个人只发送值,但是当一个人发送/接收一个参考变量时,一个人正在发送一个别名或一个引用.


更新:2015年11月11日

C聊天室进行了长时间的辩论,在阅读了这个问题的评论和答案之后,我意识到可以有另一种方式来看待这个问题,另一种观点是.

让我们看一些简单的C代码

int i;
int *p = &i;
*p = 123;
Run Code Online (Sandbox Code Playgroud)

在这种情况下,可以使用术语,p的值是对i的引用.因此,如果是这种情况,那么如果我们向int* p函数发送相同的指针(),可以认为,因为i引用被发送到函数,因此这可以被称为pass-by-reference.

所以,这是一个术语问题和观察场景的方式.

我不会完全不同意这一论点.但对于一个完全遵循这本书和规则的人来说,这是错误的.


注意:更新的灵感来自于这个聊天.

  • 在那种情况下,我会说使用指针解释传递引用是非常误导的,并且也从未明确地说过指针仍然在C中按值传递. (7认同)
  • 不仅是一些教授,而且有些书也将其作为参考文献来解决. (4认同)
  • @Insane我不认为这是误导,它只是在不同的环境中使用 - "引用"意味着现在有点不同,有C++和C#等语言.更一般地说,指针*是对值的引用.他们现在没有我们与参考文献相关联的其他属性.既然你的老师领导的课程明确是关于C(而不是C++),那就完全没问题了.你基本上抱怨用"计算机"这个词来指那些计算东西的人 - 嗯,这就是它的含义!当然,今天你想象一台机器,但这只是你的背景. (2认同)

小智 32

参考是一个重载的术语; 一般来说,引用只是一种引用某种东西的方式.指针指向指向的对象,并且通过(通过值)传递指向对象的指针是在C中通过引用传递的标准方式.

C++引入了引用类型作为表达引用的更好方式,并引入了技术英语的歧义,因为我们现在可以使用术语"通过引用传递"来引用使用引用类型来通过引用传递对象.

在C++上下文中,前者的使用是IMO,不推荐使用.但是,我认为前一种用法在其他情况下很常见(例如纯C),其中没有歧义.

  • 显然,指针是一个引用...只是不是一个c ++和引用......但它指的是一些内存块 (4认同)

hac*_*cks 17

C甚至有"通过引用传递"吗?

并不是的.

严格来说,C总是使用pass by value.您可以自己模拟通过引用传递,通过定义接受指针的函数然后&在调用时使用运算符,并且当您将数组传递给函数,编译器将基本上为您模拟它(通过传递指针,请参阅问题6.4 et人).

查看它的另一种方法是,如果参数具有类型,比如说,int *则通过引用传递整数,并且通过值传递指向整数的指针.

从根本上说,C没有任何真正等同于通过引用或引用参数的正式传递.

为了演示指针是按值传递的,让我们考虑使用指针进行数字交换的示例.

int main(void)
{
    int num1 = 5;
    int num2 = 10;

    int *pnum1 = &num1;
    int *pnum2 = &num2;
    int ptemp;

    printf("Before swap, *Pnum1 = %d and *pnum2 = %d\n", *pnum1, *pnum2);
    temp = pnum1;
    pnum1 = pnum2;
    pnum2 = ptemp;

    printf("After swap, *Pnum1 = %d and *pnum2 = %d\n", *pnum1, *pnum2);
}
Run Code Online (Sandbox Code Playgroud)

而不是交换数字指针被交换.现在为此做一个功能

void swap(int *pnum1, int *pnum2)
{
     int *ptemp = pnum1;
     pnum1 = pnum2;
     pnum2 = temp;
}

int main(void)
{
    int num1 = 5;
    int num2 = 10;

    int *pnum1 = &num1;
    int *pnum2 = &num2;

    printf("Before swap, *pnum1 = %d and *pnum2 = %d\n", *pnum1, *pnum2);
    swap(pnum1, pnum2);

    printf("After swap, *pnum1 = %d and *pnum2 = %d\n", *pnum1, *pnum2);
}
Run Code Online (Sandbox Code Playgroud)

繁荣!没有交换!


一些教程提到指针引用为引用调用,这是误导性的.请参阅此答案,了解通过引用传递和传递值之间区别.


R S*_*ahu 16

从C99标准(强调我的):

6.2.5类型

20可以从对象和函数类型构造任意数量的派生类型,如下所示:

...

- 指针典型可以从函数类型或对象类型派生,称为引用类型.指针类型描述一个对象,其值提供对引用类型的实体的引用.从引用类型T派生的指针类型有时被称为"指向T "的指针.从引用类型构造指针类型称为"指针类型派生".指针类型是完整的对象类型.

基于以上所述,你的教授所说的是有道理的,也是正确的.指针通过值传递给函数.如果指针指向有效实体,则其值提供对实体的引用.

  • 嗯,是的,但我们又回到了C,C++苹果和橘子......例如,C中没有`void swap(float&x,float&y)`,只有`void swap(float*x,float*) Y)` (8认同)

小智 10

"通过引用传递"是一个概念.是的,您正在传递指向函数的指针的值,但在该实例中,该指针的值用于引用该变量.

其他人使用螺丝刀类比来解释说通过引用传递指针是错误的,说你可以用硬币拧螺丝,但这并不意味着你会把硬币称为螺丝刀.我会说这是一个很好的类比,但他们得出了错误的结论.事实上,虽然你不会要求硬币是一把螺丝刀,你仍然会说你用螺丝拧紧螺丝.即使指针与c ++引用不同,你使用它们做的通过引用传递的.


小智 6

C按值,句点传递参数.但是,指针是一种可用于通过引用有效传递参数的机制.就像硬币可以有效地用作螺丝刀一样,如果你有合适的螺丝钉:甚至可以选择一些螺丝切割以便与硬币一起使用.他们仍然不会将硬币变成实际的螺丝刀.

C++仍然按值传递参数.C++引用比指针更有限(虽然有更多的隐式转换)并且不能成为数据结构的一部分,并且它们的使用看起来更像通常的引用调用代码看起来,但是它们的语义,同时非常适合为了满足call-by-reference参数的需要,它们比纯var函数调用实现(如Fortran参数或Pascal 参数)更有形,你可以在函数调用上下文之外完美地使用引用.


Bob*_*Run 5

你的教授是对的.按值,它被复制.通过引用,它不会被复制,引用说明它在哪里.

通过值,您将一个int传递给一个函数,它被复制,对副本的更改不会影响原始函数.

通过引用,传递相同的int作为指针,它不被复制,您正在修改原始.

通过引用,一个数组总是通过引用,你的数组中可能有十亿个项目,只是说它在哪里,你正在修改原始数据更快.