c语言的传值和传址

我们都知道C语言中函数传参有两种方式:传值和传址

传值:

实参把值传给形参,但没有传地址,即对实参的修改无效;生成临时变量

核心原理:函数会对形参和中间变量重新分配空间

Void Swap(int pLeft, int pRight)
{
int a=10,b=20;
Swap(a,b);
}

优点:安全(函数的副作用不会影响外部实参),局部变量值的交换对主函数的变量无影响。

缺点:不能通过修改形参来改变外部实参

传地址:

实参把自己的内存地址传给了形参,这样对实参的修改就有效了;同样也生成临时变量-该临时变量为外部实参地址

Void Swap(int* pLeft, int* pRight)
{
    int tmp=*pLeft;
    *pLeft=*pRight;
    *pRight=tmp;
} 

优点:节省空间,效率高,改变形参可以修改外部实参 

缺点:指针不安全,代码难度提高,可能在不用修改外部实参时反而将其修改了

传地址有以下3种方法:

(1)全局变量(把参数定义为全局变量,一次性分配空间,传地址,函数调用时无需访问直接使用)

(2)指针是传值的,但指针的间接引用是传地址的

(3)数组是传地址的,因为数组对内存要求比较苛刻,系统对数组不再分配空间,而是传地址

实例分析:

例1:

void swap(int x,int y)
{
    int tmp=x;
    x = y;
    y = tmp;
}
int main(void)
{
    int a = 3;
    int b = 4;
    swap(a,b);
}

传值时,在主函数中调用swap()无法改变a,b的值,因为传给swap()的参数实际上是a,b变量的一份拷贝_a,_b,他们和a,b的地址并不一样,当调用完swap后,它所占的内存空间会被释放,所以a,b的值并没有被改变。

例2:

void swap(int* x,int* y)
{
    int tmp;
    tmp = *x;
    *x = *y;
    *y = tmp;
}
int main(void)
{
    int a = 3;
    int b = 4;
    swap(&a,&b);
}

传址时,通过调用swap()可以改变a,b的值,因为此时传递的是a,b的地址,在swap()中改变*x,*y的值就相当于在改变a,b的值,因为他们的地址是一样的,即使调用完swap后,它所占的内存空间会被释放,但a,b的值已被改变。

例3:

void getMemory(char* p,int num)
  {
p = (char*)malloc(num);
}

int main(void)
{
    char* str = NULL;
    getMemory(str,10);
    strcpy(str,"hello");
    printf("%s\n",str);
    return 0;
}

运行会报段错误,它和传址调用有区别:getMemory()函数是想改变指针变量str本身的值,而不是改变*str的值,虽然在getMemory()函数中p的值会被改变,但当它调用完后,p会被释放,所以str的值还是为空,要想改变str的值,应该传&str。

通过例子可以看出,不管是传址还是传值都是传的变量的一份拷贝,要想改变变量本身的值,就应该传该变量本身的地址。

猜你喜欢

转载自blog.csdn.net/tanrui519521/article/details/79925843
今日推荐