形参为指针的函数是否为形参分配空间

形参为指针的函数是否为形参分配空间,第1张

要理解你这个问题,你必须首先明白传值和传指针的区别。

给一个函数传值,实参会把具体的值传给函数的形参,函数拿到这个值以后会产生一个临时变量(这个临时变量你是看不到的),你的整个函数的 *** 作就是在 *** 作这个临时变量,所以你在函数内部给,形参赋值并不能改变实参的值。

给一个函数传指针,实参会把外部存储值的地址给形参,注意这是地址,证明外部已经申明了存储该实参值的内存,不然不会存在存储某值的地址,所以内部不再需要分配空间;当然有的时候我们的实参只申明了一个指针,并没有申请地址,这个时候编译是没有问题的,但是在运行的时候我们会把实参指向的内容的地址传给形参,而此时实参并没有申请空间,这个时候就会出现一个错误。

所以,当我们传递给函数一个指针的时候,我们的目的是要 *** 作某一块内存,既然要 *** 作某一块内存,那么这块内存首先必须存在,既然已经存在在函数内部在分配空间就没有必要,即使分配了也没有任何意思,如果不释放还会出现内存泄露情况

形参:全称为"形式参数"是在定义函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传如的参数

实参:全称为"实际参数"是在调用时传递个该函数的参数

形参和实参的类型必须要一致,或者要符合隐含转换规则,

当形参和实参不是指针类型时,在该函数运行时,形参和实

参是不同的变量,他们在内存中位于不同的位置,形参将实

参的内容复制一份,在该函数运行结束的时候形参被释放,

而实参内容不会改变

而如果函数的参数是指针类型变量,在调用该函数的过程

中,传个函数的是实参的地址,在函数体内部使用的也是

实参的地址,即使用的就是实参本身所以在函数体内部

可以改变实参的值

给你一个很简单的例子:

int f(int b) /b为形参/

{ return b;}

main()

{int a=1; <br>printf("%d",f(a));/a为实参/ <br>}

字符指针,可以指向1个字符的地址。

字符串:表示为一个连续内存的多个字符地址

所以1个字符的地址也表示了以这个字符地址开头的任意长度的字符串。(前提要申请内存空间)

所以这里a既表示了其指向的字符地址 也表示了以a指向地址开头的字符串

相当于字符数组。所以会有上面代码的写法。

情况1 需要读入的数据是比较大的数据,使用指针作为参数可以节省堆栈

比如 定义1个结构体

typedef struct test

{

char buffer1[10000];

char buffer2[10000];

//后面还有一大堆成员

}test_ts;

void Func1(test_ts t1)

{

//函数体是对t1成员进行Read处理

}

void Func2(test_ts t1)

{

//函数体是对t1成员进行Read处理

}

上面2个函数功能其实一样,但函数Func2参数只是一个指针占的空间就4 Byte,

Func1参数是一个结构体,占的空间就看成员多少,但例子的使用的堆栈最少20000Byte了。

情况2 需要对数据进行改写

一般对应的数据是数组或结构体数据。

比如memset函数函数,用于把传入指针的数据写入对应的数据。

具体函数体内容不贴了,baidu查下吧。

例如还是这个结构体test_ts

test_ts t2;

如果需要将t2的每个成员初始化成0,可以把每个成员挨个赋值成0。

但如果用下面这样代码

memset(&t2,0,sizeof(t2));

一行搞定

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/11678724.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-17
下一篇 2023-05-17

发表评论

登录后才能评论

评论列表(0条)

保存