函数传参问题

函数传参:
一、总结:
形参只是实参的一份临时拷贝。实例化时,在栈中形成栈帧
1、若仅改变变量的内容,传一级指针(变量所指向(存储)的地址)
2、若要改变变量的内存空间,或地址,需传二级指针(变量自身的地址)
二、讲解:
传一级指针:变量所指向(或存储)的地址,退出函数时,释放变量所开辟的空间。不释放变量中成员的地址空间
作用:
只能改变变量的内容,包括变量中成员的地址,空间。
不能改变变量的地址,空间。若改变了变量的地址空间,则之后操作无效

传二级指针:即变量自身的地址,退函数时,变量所开辟的空间不被清空
传变量自身的地址(如:&指针变量名),此时变量所指向的地址(即指针变量名)相当于变量的内容
能改变变量的内存空间或地址,及变量中的内容

说明一下:arr[i]==*(arr+i),
一维数组名,是变量本身的地址,使用一级指针传参
指针数组名,是变量本身的地址,需使用二级指针
二维数组名,是变量本身的地址,但需使用指针数组传参,而不是二级指针,
因为二维数组是由多个一维数组构成的,使用(*arr)[N]或arr[][N]传参,要指明列的大小
动态开辟二维数组空间(arr[M][N])?
解:先开辟M大的空间,在开辟N个M大的空间,每次释放只能释放一个M个大小的空间

代码实例解析:

#include<stdio.h>
#include<stdlib.h>

typedef struct Seqlist
{
    int  data;
    char * sch;
}node;

int test1(node * seq)//一级指针
{
    //sch无内存空间
    //*seq->sch='1';//错误,内存泄漏
    seq->sch="123";//正确,为sch在文字常量区开辟内存空间
    //为结构体成员开辟内存空间,sch指向新内存空间(堆)
    seq->sch=(char*)malloc(sizeof(char)*10);
    seq->sch[0]='2';//正确,sch已有内存空间(堆区地址)
    seq->sch[1]='\0';
    seq->sch="456";//sch空间变为文字常量区的地址
    //seq->sch[0]='7';//错误,文字常量区地址内容不可改变
    seq->data=20;
    //以下对seq的变量开辟内存空间,操作无效
    //为结构体指针开辟内存空间,seq指向新内存空间
    seq=(node*)malloc(sizeof(node));
    seq->data=10;
}//结构体指针临时变量内存空间被释放,成员sch空间保留

int test2(node ** seq)//二级指针
{
    //为结构体指针*seq开辟内存空间(堆区地址)
     *seq= (node*)malloc(sizeof(node));
    //为内部成员开辟空间(堆区)
    (*seq)->sch=(char*)malloc(sizeof(char)*10);
    (*seq)->sch[0]='0';//内存空间为堆区
    (*seq)->sch="321";//自动为sch在文字常量区开辟空间,并赋值(sch为文字常量区)
    (*seq)->data=10;
}//所开辟内存空间不被销毁

void test3(char **ch)//二级指针,可开辟内存空间
{
    printf("%p\n",ch[1]);
    //*ch[1]='1';//错误,ch[1]无内存空间
    ch[1]=(char*)malloc(1);//在堆上开辟一块内存空间
    *ch[1]='1';//正确,ch[1]有内存空间
    printf("%p\n",ch[1]);
    ch[1]="123456789011111111111";//重新给ch[1]分配一块内存空间(文字常量区)
    printf("%p\n",ch[1]);
}//开辟内存空间不消毁

void test4(char * ch)//1级指针,仅可以数值操作
{
    printf("%p\n",ch);
    *ch='1';//正确,ch有内存空
    *++ch='\0';
    //一下部分进行地址有关操作无效
    ch=(char*)malloc(1);//在堆上开辟一块内存空间
    *ch='2';//正确,ch有内存空间
    printf("%p\n",ch);
    ch="123456789011111111111";//重新给ch[1]分配一块内存空间(文字常量区)
    printf("%p\n",ch);
}//开辟的内存空间销毁

int main()
{
    node * seqlist=NULL;
    char * ch[3];

    test3(ch);//二级指针
    printf("%p\n",ch[1]);
    printf("%s\n",ch[1]);

    ch[1]=(char*)malloc(1);//在堆上开辟一块内存空间
    printf("%p\n",ch[1]);
    test4(ch[1]);//1级指针,不可传无内存空间的地址
    printf("%p\n",ch[1]);
    printf("%s\n",ch[1]);//1

    seqlist= (node*)malloc(sizeof(node));
    test1(seqlist);//一级指针传参,内存空间不可为空
    printf("%d\n",seqlist->data);
    printf("%s\n",seqlist->sch);

    free(seqlist);
    test2(&seqlist);
    printf("%d\n",seqlist->data);
    printf("%s\n",seqlist->sch);

    system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值