passing by preference

passing by value

值互换:

#include <stdio.h>

void swap(int a, int b);

int main(void)
{
    // 键盘录入两整数
    int x, y;
    printf("请输入两个整数:");
    scanf("%d %d", &x, &y);
    printf("交换前 x = %i, y = %i\n", x, y);

    // 值互换
    swap(x, y); /* 实现:x和y值互换 */
    printf("交换后 x = %i, y = %i\n", x, y);
}

void swap(int a, int b) /* 按值传递 */
{
    int temp = a;
    a = b;
    b = temp;
}

结果:
在这里插入图片描述

我们发现,值并么有发生互换,这是因为,a 和 b的声明周期只存在于{}内,当调用完函数后出栈,就没了,并不会影响到原始数据,即main函数中的’x’和’y’

那么如果,我们定义的函数想要对原始数据进行修改,而非只是从函数那里得到一个结果的话,要怎么做呢?
指针,指针作用其二——处理地址处数据,即可以对地址处的数据进行修改和取出;因此,我们不妨获取main函数中’x’和’y’的内存地址,然后再进行互换

void swap(int* a, int* b)  /* 按引用传递 */
{
    int temp = *a; /* 临时变量,获取地址处数据 */
    *a = *b;
    *b = temp;
}

结果:
在这里插入图片描述
当然,要传入内存地址,main函数中的一处仍需修改:

/* 以前版本
* swap(x, y);
* /
* 
// 新版本
swap(&x, &y); /* 传递的是x和y的内存地址 */

指针呢?

如果我们需要通过函数改变main函数中的指针变量时,又如何处理?
和上面的值互换类似,指针亦是一种变量类型
在这里插入图片描述
我们可将,指针看做一种新的变量类型
整型指针
在这里插入图片描述
那么按引用传递,就类似于int、char、float…
因此,若我们想在函数中改变一个指针本身(即,让指针指向不同的内存地址),你需要传递该指针的地址。这通常被称为“指向指针的指针”(pointer to pointer)。通过传递指针的地址,函数可以修改调用者指针的值。

例、实现函数(结构体指针)

push_front(value) —— 添加元素到链表的首部
在这里插入图片描述
结果:
在这里插入图片描述
图解:
在这里插入图片描述

代码:

// 单向链表,无尾指针
#include <stdio.h>
#include <stdlib.h>

typedef struct node
{
    int number; /* 存储数据 */
    struct node* next; /* 指向下一个节点 */
} node;

node* creatLink(int arry[], int length); /* 创建链表, length为数组长度 */

void  printLink(node* list); /* 打印链表中的元素 */

void freeLink(node* list); /* 释放链表 */

void push_front(int value, node** list); /* 在链表首,添加元素;为什么是void?因为passing by preference */

int main(void)
{
    // 创建链表
    int arry[] = {1, 2, 3, 4}; /* 修改数组的值,可改变链表数据;注意:是整数数组! */
    int length = sizeof(arry) / sizeof(arry[0]); /* 获取整数数组长度 */
    node* list = creatLink(arry, length);

    // 打印链表
    printLink(list);

    // 在链表前添加元素
    push_front(666, &list); /* 将666添加到链表首 */
    printf("新");
    printLink(list);

    // 释放链表
    freeLink(list);
}

void push_front(int value, node** list)
{
    node* n = malloc(sizeof(node));
    n->number = value;
    n->next = *list;
    *list = n;
}


node* creatLink(int arry[], int length)
{
    // 创建链表
    node* list = NULL; /* 无尾指针;list为链表头部 */
    for(int i = 0; i < length; ++i)
    {
        node* n = malloc(sizeof(node)); /* 创建节点 */
        n->number = arry[i];
        n->next = NULL;

        // 链表
        if(list == NULL)
            list = n; /* 链表的第一个元素 */
        else
        {
            node* ptr;
            for(ptr = list; ptr->next != NULL; ptr = ptr->next) /* 将链表的最后一个元素指向新的节点 */
            ; /* 只需遍历到链表的最后一个元素,无需方法体 */
            ptr->next = n;
        }
    }
    return list;
}

void printLink(node* list)
{
    if(list == NULL) /* 空链表 */
        printf("链表中的元素有:[]\n");
    else
    {
        node* ptr;
        printf("链表中的元素有:[");
        for(ptr = list; ptr->next != NULL; ptr = ptr->next) /* 遍历到倒数第二个元素 */
            printf("%d, ", ptr->number);
        printf("%d]\n", ptr->number);
    }
}

void freeLink(node* list)
{
    // free链表:类似于吃糖豆人——先得到下一个节点,再释放前一个节点
    node* ptr = list;
    while(ptr != NULL)
    {
        ptr = ptr->next;
        free(list);
        list = ptr;
    }
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值