c语言函数参数为指针的情况分析

指针取*解引用:表示的是指针所指向内存单元中内容;或者理解为该内存空间。

指针传递其实也是一种值传递,只不过传递的是地址值,如果通过该地址取*解引用,是可以改变形参指针的原值的,但如果只是指针的值发生变化的话,并不会影响实参指针及其原值。

故:可以这么说:

函数参数均为值传递

函数参数为指针时的情况分析:

1)实参已经初始化(重要)数组名作为参数传递,实际也是传递的指针

例如://传递指针改变原值的情况

char ch[1024];
int* func(char *p)
{
    memcpy(p,"hello");//是对*ch的值进行改变,地址没有变化,原值变了。
}

//函数调用:
func(ch);

分析:实参已经被初始化了,即:指针ch已经指向了内存空间。

2)实参未初始化或者值为NULL。

//无法改变形参值,仅仅是地址形式的值传递

char *ch = NULL;
int* func(char *p)
{
    p = (char*)malloc(sizeof(char)*5);
    p[0]='h';
    
}

//函数调用:
func(ch);

//仅仅是将NULL的值传递给形参,且函数内并没有解引用,故既不能改变实参指针也没有指针原型可以改变。当然也无法初始化实参。

解释:将NULL值复制给了指针p,但是函数内p又被重新赋值了,这只是单纯的值传递,无法改变实参的值。因为,函数内,也没有对指针的原型做改变,而仅仅是对指针进行了赋值。 

改正方法一:采用传引用的方式,而不是值传递的方式
 

char *ch;
int* func(char* &p)
{
    p = (char*)malloc(sizeof(char)*5);
    p[0]='h';
    
}

//函数调用:
func(ch);

 改正方法二:采用指针传递,而不是值传递,因为实参本身是指针,所以函数参数可以为二重指针

char *ch;
int* func(char** p)
{
    *p = (char*)malloc(sizeof(char)*5);
    (*p)[0]='h';
    
}

//函数调用:
func(&ch);

改正方法三:将指针通过返回值返回。

char *ch;
void* func(char* p)
{
    p = (char*)malloc(sizeof(char)*5);
    p[0]='h';
    return p;
}

//函数调用:
ch = func(ch);

//do sth.

free(ch);

 实参为NULL的情况

//实参虽然初始化为NULL了,仍然不能直接使用//因为指针仍然没有指向内存
char *ch=NULL;
int* func(char*p)
{
   if(!ch)
        printf("error");
    
}

//函数调用:
func(ch);

总结

1)如果函数形参要通过指针传递,且该指针没有初始化,则要么采用(二重)指针的形式,要么采用引用的形式进行参数初始化;

如果实参指针已经初始化了,则除通过上述方法外,还可以直接通过值传递即可。

其实,函数传的参数都是一样的,包括指针和普通变量,只要实参是未初始化的,肯定是通过指针和引用传参(未初始化,当然不能通过值传递了。。。);如果实参已经初始化,则除可以通过指针、引用传参外,还可以通过原值传递。

所以:

  • 可以通过实参是否已经初始化,可以推断是什么类型的传参方式。
  • 如果形参为指针,查看函数内是否对该指针进行解引用了,如果解引用了,可以改变原值,如果没有则对原值及实参指针没有影响。

只有指针和引用才能改变实参原值,如果原值是普通变量,则参数一重指针,如果原值为一重指针,则参数为二重指针。

2)函数参数均为值传递。

另,参考示例可以参看本文

实际中经常用的是结构体指针作为形参的形式

typedef struct{
    char *mm;
    int nn;
    float gg;

}STU;


void func_1(float* p)
{
    *p = 3.14;
    
}
void func(STU* p)
{
    p->nn = 2;
    p->mm = (char*)malloc(sizeof(char));
    func_1(&p->gg);
    
}

STU ch;

//函数调用:
func(&ch);

  • 7
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值