代码之家  ›  专栏  ›  技术社区  ›  Kevin Meredith

C编程-通过引用传递

  •  6
  • Kevin Meredith  · 技术社区  · 14 年前

    #include <stdio.h>
    #include <stdlib.h>
    
        void foo(char buf[])
        {
          buf[0] = 'A';
        }
    
        int main(int argc, char *argv[])
        {
          char buf[10];
    
          buf[0] = 'B';
          printf("before foo | buf[0] = %c\n", buf[0]);
          foo(buf);
          printf("after foo | buf[0] = %c\n", buf[0]);
    
          system("PAUSE"); 
          return 0;
          }
    

    输出:

    before foo | buf[0] = 'B' 
    after foo | buf[0] = 'A'
    
    12 回复  |  直到 14 年前
        1
  •  12
  •   James McNellis    14 年前
    void foo(char buf[])
    

    void foo(char* buf)
    

    当你叫它的时候, foo(buf) ,则按值传递指针,从而生成指针的副本。

    指针的副本指向与原始指针相同的对象(在本例中,指向数组的初始元素)。

    在C++具有通过引用语义的意义上,C没有传递引用语义。C中的所有内容都是通过值传递的。指针用于获取按引用传递的语义。

        2
  •  4
  •   Nathan Fellman    14 年前

    数组只是使用指针的一种奇特方式。当你经过的时候 buf 但是当你取消引用指针时,你仍然在引用它指向的字符串。

        3
  •  2
  •   Nikolai Fetissov    14 年前

    void foo( char buf[] );
    

    与相同

    void foo( char* buf );
    

    数组参数是 腐朽的 指向其第一个元素的指针。

        4
  •  2
  •   John Bode    14 年前

    数组的处理方式与其他类型不同;不能在C中传递数组“按值”。

    Online C99 standard (draft n1256)

    字符串文字用于初始化数组,具有类型为的数组类型的表达式为 转换为类型指针指向类型的表达式,该类型指向 数组对象,不是左值。如果数组对象具有寄存器存储类,则 行为未定义。

    在通话中

    foo(buf);
    

    buf 不是的操作数 sizeof & 第一个元素的值传递给foo。因此,你要做的任何事 缓冲器 在里面 foo() 将反映在 main() . 由于数组下标是如何定义的,所以可以对指针类型使用下标运算符,以便

    在函数参数声明的上下文中, T a[] T a[N] 是同义词 T *a 只有 如果这是真的。

        5
  •  1
  •   Marcus Johansson    14 年前

    *char buf[]实际上意味着char**,所以您是通过指针/引用传递的。 这说明buf是一个指针,在 主要的

        6
  •  1
  •   Pablo Santa Cruz    14 年前

    因为你正在传递一个指向 buf (按值)。所以被指的内容 缓冲器 改变了。

        7
  •  1
  •   Shawn D.    14 年前

    有了指针就不同了;传递的是值,但传递的是指针的值,它与数组的值不同。

        8
  •  1
  •   Dustin Getz    14 年前

    数组和指针(几乎)是一回事。

    int* foo = malloc(...)
    

    foo[2] 与相同 *(foo+2*sizeof(int))

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

    它也是合法的(将编译和工作相同)写

    int main(int argc, char **argv)
    

    还有

    int main(int argc, char argv[][])
    

        9
  •  0
  •   tenfour    14 年前

    为了传递该值,函数需要知道参数的大小。在这种情况下,您只是传递一个指针。

        10
  •  0
  •   ravibhagw    14 年前

    如果要保留原始数组的内容,可以将字符串复制到函数中的临时存储器中。

    edit:如果将char数组包装在一个结构中并传递该结构,会发生什么?我相信这也行得通,尽管我不知道在编译器级别会产生什么样的开销。

        11
  •  0
  •   noisy    14 年前

    void foo(char buf[])
    

    表示将使用[]表示法。不是要使用数组的哪个元素。

    如果您想指出这一点,您想得到一些特定的值,那么您应该将此函数声明为

    void foo(char buf[X]); //where X would be a constant.
    

    voi foo(char value);
    

    所以。。。

    是一个声明,说明要使用哪个符号([]-part),它还包含指向某些数据的指针。

    foo(buf);
    

    相当于&buf[0]。所以。。。这是一个指针。

        12
  •  0
  •   nmichaels    14 年前

    在函数参数中使用数组是一种很好的方法,它可以向您的API用户发出这样一个信号:这个东西应该是一块被分割成n字节大小的内存块,但是不要指望编译器会关心您是否拼写 char *foo char foo[] char foo[12] 在函数参数中。他们不会的。