C语言——二级指针的输入输出特性

本内容以二级指针输入输出为主题,在后边记录了一些位运算知识。

输出特性和输入特性是什么?

输入特性:主调函数创建空间,被调函数使用空间
输出特新:被调函数创建空间,主调函数使用空间

输入特性例程:

在堆中创建空间在这里插入图片描述

void test01() //在堆中创建指针区域指向值的地方
{
    int** pAdress = malloc(sizeof(int *)*5);  //因为堆中创建的是一级指针,所以指向他们的指针要为二级指针
    //在栈上创建数据
    int a1 = 1;
    int a2 = 2;
    int a3 = 3;
    int a4 = 4;
    int a5 = 5;
   //将值与堆中指针対映
    pAdress[0] = &a1;
    pAdress[1] = &a2;
    pAdress[2] = &a3;
    pAdress[3] = &a4;
    pAdress[4] = &a5;
    //打印数据
    myprint(pAdress, 5);
    //释放内存
    if (pAdress != NULL)
    {
        free(pAdress);
        pAdress = NULL;
    }
}

在栈中创建空间
在这里插入图片描述

void test02()
{
    int* pAdress[5];

    for (int i = 0; i < 5; i++)
    {
        pAdress[i] = malloc(4);//在堆中分配空间并把地址给在栈的空间

        *(pAdress[i]) = i + 1; //给对中空间赋值
    }
    myprint(pAdress, 5); //打印数据
    Freespace(pAdress, 5); //释放空间
}

打印数据

void myprint(int** pAdress,int len) //形参为二级指针与长度
{
    for (int i = 0; i < len; i++)
    {
        printf("%d\n",*(pAdress[i]));//pAdress[i]中存放着栈中数据的地址
    }
}

释放函数

void Freespace(int* pAdress,int len)
{
    for (int i = 0; i < len; i++)
    {
        free(pAdress[i]); //此处如下图为每个堆空间的地址
        pAdress[i] = NULL;
    }
}

在这里插入图片描述

输出函数的特性

void test()
{
    int* p = NULL;  //此处为要指向被调函数中申请的空间地址所需要的的指针

    allocate(&p); //被调函数传入指针地址 因为函数参数是二级指针按地址传递

    printf("主函数中:%p\n",p);

    Printshow(&p,5);

    Freespace(p);//此为Freespace(int* p) 按值传递 所以需要下面手动置空使它从野指针变为空指针  如果为Freespace(int** p)则此处传入的是&p按地址传递该函数栈中空间直接被修改
    if (p != NULL)
    {
        p = NULLprintf("p不为空\n");
    }
}
void allocate(int** p)   //如果此处是(int* p)则在该函数的栈中,函数结束该空间释放
{
    int* temp = malloc(sizeof(int) * 5); //申请空间
   //为申请的空间赋值
    for (int i = 0; i < 5; i++)
    {
        *(temp+i) = i + 1;
    }
    //因为传入的是p的地址要通过一级指针将地址值写入p中
    *p = temp; 
}

打印数据函数

/*形参要是用二级函数是因为当allocate(),执行完以后它的栈空间会释放也就是
temp将会为空,所以只能使用二级指针,通过之前记录的地址值访问*/
void  Printshow(int** p, int len)
{
    for (int i = 0; i < len; i++)
    {
        printf("%d\n", (*p)[i]);//先找到堆空间首地址然后再根据偏移读值
                                //此处类似于数组输出
    }
}

内存释放
void Freespace(int** p)//此处通过高级指针释放 p也NULL,诺这里参数为int *p则需要单独释放p
{
free(*p);
*p = NULL;
}

void Freespace(int* p)//此处通过高级指针释放 p也NULL,诺这里参数为int *p则需要单独释放p
{
free(p);

p = NULL;

}
在这里插入图片描述

位运算

或运算 可以给某一位置1,只需要使其与所要置1位为1其余位为0的数进行或运算即可
异或 两者不同为1 两个数异或运算得出第三个数,这三个数两两运算得出的结果为剩下的那个数

两个数进行交换

void test04()
{
	int num1 = 5;
	int num2 = 9;
    //常规方法 需要中间变量
	/*int tmp = num1;
	num1 = num2;
	num2 = tmp;*/
	
    //通过异或运算的特性 不需要中间变量
	num1 = num1 ^ num2;
	num2 = num1 ^ num2;
	num1 = num1 ^ num2;
    
    //通过两数和差  也不需要中间变量
	//num1 = num1 + num2;
	//num2 = num1 - num2;
	//num1 = num1 - num2;


	printf("num1 = %d\n", num1);
	printf("num2 = %d\n", num2);

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值