一级指针和二级指针,取地址和不取地址调用函数区别及其应用

简介: 一级指针和二级指针,取地址和不取地址调用函数区别及其应用

1.指针定义区别


一级指针是指向某个数据的指针,它存储的是该数据的内存地址。通过一级指针可以访问和修改该数据的值。一级指针多用于单个数据的操作,例如传递参数、返回结果等。


二级指针是指向一级指针的指针,它存储的是一级指针的内存地址。通过二级指针可以访问和修改一级指针指向的数据的值。二级指针多用于对一级指针进行操作,例如动态内存分配和释放、指针数组等。


一级指针和二级指针的应用主要有以下几个方面:

动态内存管理:通过二级指针可以对动态分配的内存进行管理,例如创建和销毁动态数组、链表等数据结构。

参数传递:通过一级指针可以将变量的地址传递给函数,并在函数中修改变量的值。通过二级指针可以将指针的地址传递给函数,并在函数中修改指针指向的数据。

返回多个值:通过二级指针可以在函数中修改指针指向的数据,并将修改后的数据通过指针返回。

多级数据结构:通过二级指针可以实现多级数据结构,例如二维数组的动态分配和访问、树的遍历和修改等。


总之,一级指针和二级指针在C和C++中是非常重要的概念,能够帮助程序员更灵活地操作内存和数据结构。对于初学者来说,理解和掌握一级指针和二级指针的使用方法是非常基础和重要的一步。


2.举例比较


struct Node{
    int data;
    Node* next;
};
void insertNode(Node** head, int data){
    Node* newNode = new Node();
    newNode->data = data;
    newNode->next = *head;
    *head = newNode;
}
int main(){
    Node* list = nullptr;
    insertNode(&list, 1);
    insertNode(&list, 2);
    insertNode(&list, 3);
   
    Node* currentNode = list;
    while(currentNode != nullptr){
        cout << currentNode->data << " ";
        currentNode = currentNode->next;
    }
   
    return 0;
}


在上述示例中,insertNode函数接收一个二级指针head作为参数,它通过将新节点的next指针指向*head,然后将*head指向新节点,来在链表的前端插入一个节点。


在main函数中,通过传递&list作为参数调用insertNode函数,实际上是将链表的头指针list的地址传递给了二级指针head。这样,在insertNode函数中可以通过修改*head来改变链表的头指针。最终,遍历链表并输出结果。


3.函数参数调用时取地址和不取地址的区别


#include <stdio.h>
#include <stdlib.h>
struct Node{
    int data;
    struct Node* next;
};
void insertNode(struct Node* head, int data){
    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
    newNode->data = data;
    newNode->next = NULL;
   
    // 将新节点插入链表末尾
    if(head == NULL){
        head = newNode;
    } else {
        struct Node* temp = head;
        while(temp->next != NULL){
            temp = temp->next;
        }
        temp->next = newNode;
    }
}
void printList(struct Node* head){
    struct Node* currentNode = head;
    while(currentNode != NULL){
        printf("%d ", currentNode->data);
        currentNode = currentNode->next;
    }
    printf("\n");
}
int main(){
    struct Node* list = NULL;
   
    insertNode(list, 1);
    insertNode(list, 2);
    insertNode(list, 3);
   
    printList(list);
   
    return 0;
}


在上述示例中,insertNode函数接收一个指向链表头节点的指针head作为参数,用于将新节点插入链表末尾。然而,这里的参数head并未取地址传递,即没有改变main函数中的链表list。


运行以上代码,输出为空,因为链表并没有被正确构建。原因在于在insertNode函数中,head是一个局部变量,它只是指向了传递进来的链表头节点的一个副本,所以对head的修改不会影响实际的链表。


为了解决这个问题,我们需要将头节点的指针的地址传递给insertNode函数。修改main函数中的调用如下:


insertNode(&list, 1);
insertNode(&list, 2);
insertNode(&list, 3);

将链表头节点指针的地址传递给insertNode函数后,可以正确构建链表,并输出结果:


1 2 3

通过取地址传递参数,可以在函数内部修改实际的链表,使对链表的操作在函数外部可见。

相关文章
|
24天前
|
存储 安全 编译器
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。
|
1月前
链表指针的传参,传值和传地址
本文讨论了链表操作中指针传参的问题,特别是指针的传值与传地址的区别,并提供了修正代码,以确保链表插入操作能正确地修改指针指向的地址。
16 1
链表指针的传参,传值和传地址
|
30天前
|
存储 C语言
C语言指针与指针变量的区别指针
指针是C语言中的重要概念,用于存储内存地址。指针变量是一种特殊的变量,用于存放其他变量的内存地址,通过指针可以间接访问和修改该变量的值。指针与指针变量的主要区别在于:指针是一个泛指的概念,而指针变量是具体的实现形式。
|
1月前
|
C++
析构造函数就是为了释放内存,就是在局部指针消失前释放内存,拷贝构造函数就是以构造函数为模块,在堆里面新开一块,同一个变量在堆里面的地址
本文讨论了C++中构造函数和析构函数的作用,特别是它们在管理动态内存分配和释放中的重要性,以及如何正确地实现拷贝构造函数以避免内存泄漏。
37 2
|
2月前
|
传感器 物联网 大数据
C 指针在物联网的应用
在物联网(IoT)中,C 语言及其指针功能广泛应用于嵌入式系统。C 指针在内存管理、设备驱动、数据结构处理、传感器通信等方面发挥关键作用,如动态分配内存、直接访问硬件寄存器、传递复杂数据结构等,有效提升了资源受限环境下的性能和灵活性。通过函数指针和省电模式管理,还能实现事件驱动编程和节能目标,使 C 语言成为 IoT 开发的重要工具。
67 12
|
2月前
|
存储 安全 C语言
C语言 二级指针应用场景
本文介绍了二级指针在 C 语言中的应用,
|
3月前
|
算法 Java
双指针在数组遍历中的应用
文章深入探讨了双指针技术在数组遍历中的应用,通过实战例子详细解释了快慢指针和首尾指针的不同用法,并提供了解决LeetCode相关问题的Java代码实现。
|
3月前
|
存储 搜索推荐 C语言
C语言中的指针函数:深入探索与应用
C语言中的指针函数:深入探索与应用
|
4月前
|
存储
头指针和头结点的区别
头指针和头结点的区别
148 1
|
5月前
|
存储 C语言
C语言数组指针详解与应用
C语言数组指针详解与应用