函数内部的数组变量会影响c中函数外的数组变量

时间:2016-06-02 13:32:16

标签: c arrays pointers

我的代码是

appendChild

现在我没有在数组#include <stdio.h> #define MAXVAL 100 int getCharsMethod(char s[],int); main(){ char foo[MAXVAL]; int len; len=getCharsMethod(foo,5); printf("value of foo is -- %s and len is %d",foo,len); } int getCharsMethod(char s[],int lim){ int i; for(i=0;i<lim;++i) s[i]=getchar(); return i; } 中插入任何值。 但是在函数内部的数组foo[]中插入的值会反映在s[]数组中。

我刚刚将一个长度为foo[]的空foo[]数组传递给函数MAXVAL。如何在函数内的数组getCharsMethod()中插入的字符反映在{ {1}}数组。

4 个答案:

答案 0 :(得分:6)

当您将数组传递给函数时,它(基本上)只获取数组的第一个元素的地址。

所以数组sfoo使用相同的内存,这就是为什么从外部看到函数内部的写入的原因。

有人会认为这在您的代码中是显而易见的,否则char s[]甚至意味着什么?它没有长度,所以如何使用赋值给函数内的s[i]来接受存储元素。您是否希望C能够自动创建和管理神奇的增长阵列?如果是这样,那么请阅读更多关于语言的内容。它没有那样的工作。

答案 1 :(得分:2)

在通过复制其值来传递给函数的C参数中。

考虑例如

#include <stdio.h>

void f( int x )
{
    x += 10;
    printf( "Inside f x = %d\n", x );
}

int main(void) 
{
    int x = 5;

    printf( "Before call of f x = %d\n", x );
    f( x );
    printf( "After  call of f x = %d\n", x );
}   

程序输出

Before call of f x = 5
Inside f x = 15
After  call of f x = 5

这就是函数处理原始变量x的值的副本。原始变量x本身不会更改。

现在考虑一个修改过的程序

#include <stdio.h>

void f( int *px )
{
    *px += 10;
    printf( "Inside f x = %d\n", *px );
}

int main(void) 
{
    int x = 5;

    printf( "Before call of f x = %d\n", x );
    f( &x );
    printf( "After  call of f x = %d\n", x );
}

程序输出

Before call of f x = 5
Inside f x = 15
After  call of f x = 15

在这种情况下,参数通过引用传递,即函数获取原始变量x的地址,因此它会更改变量。

数组也可以通过值作为函数的参数传递。那就是函数可以处理数组的副本。但是创建整个阵列的副本是一项非常昂贵且耗时的操作。

因此在C中,当一个数组传递给一个函数时,它的指示符会被隐式转换为指向它的第一个元素的指针。并相应地将参数调整为指针。

例如,这些函数声明是等效的,并声明相同的一个函数

void f( int a[] );
void f( int a[10] );
void f( int a[100] );
void f( int *a );

因此,数组的元素实际上是通过引用传递的。您可以使用与我在帖子中的第二个演示程序中显示的方式相同的方式更改数组中的任何元素。

例如

#include <stdio.h>

void f( int *a, size_t n )
{
    for ( size_t i = 0; i < n; i++ ) *( a + i ) = i;

    printf( "Inside f array a is " );

    for ( size_t i = 0; i < n; i++ ) printf( "%d ", *( a + i ) );
    printf( "\n" );
}

int main(void) 
{
    int a[] = { 0, 0, 0, 0, 0 };
    const size_t N = sizeof( a ) / sizeof( *a );

    printf( "Before call of f array a is " );
    for ( size_t i = 0; i < N; i++ ) printf( "%d ", *( a + i ) );
    printf( "\n" );

    f( a, N );

    printf( "After  call of f array a is" );
    for ( size_t i = 0; i < N; i++ ) printf( "%d ", *( a + i ) );
    printf( "\n" );
}   

程序输出

Before call of f array a is 0 0 0 0 0 
Inside f array a is 0 1 2 3 4 
After  call of f array a is0 1 2 3 4 

答案 2 :(得分:2)

  

我刚刚将一个长度为MAXVAL的空foo []数组传递给函数getCharsMethod()

不,你没有。实际上,你不能。在C中,没有函数参数或返回值是数组。在几乎所有上下文中,数组类型的表达式的值“衰减”到指向数组的第一个元素的指针,函数的参数列表和return语句中提供的值不是例外。您传递了指向main()数组foo的第一个元素的指针。

此外,通过数组语法声明函数参数(有或没有长度)实际上将该参数声明为指针,与参数列表中给出的标称类型的数组将衰减的指针类型完全相同。这是一种语法上的便利,因为同样,函数参数不能是数组。同样,这不是禁止,而是C语义对表达式评估的结果。

因此,这些声明在语义上是相同的:

int getCharsMethod(char s[], int lim);

int getCharsMethod(char *s, int lim);

甚至

int getCharsMethod(char s[MAXVAL], int lim);
  

如何在函数内的数组s []中插入的字符反映在foo []数组中。

函数s中没有数组getCharsMethod()。只有一个指针,在您的特定呼叫期间指向main()的{​​{1}}的第一个元素。因此,对于foo(包括)与i(不包括)的长度之间的任何0foos[i]中指定相同的char } getCharsMethod()foo[i]中指定 - 不仅仅是相同的,而是相同的实际对象。

答案 3 :(得分:1)

  

当从函数发送任何数组时,接收参数if array;然后它获得基地址。

这意味着,

  • 主要参数和参数数组都包含相同的地址。
  • 因此,这隐含地作为通过引用机制调用。
  • 最后,对函数中的参数所做的任何更改都会影响主参数。

那么,为什么foo[]反映s[]

此处,在您的代码中,s获取foo的基地址,因此隐式变为 调用引用机制 ,因此对s的任何更改都会影响foo