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

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

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

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

相关文章
|
4天前
|
存储 安全 C++
C++中的引用和指针:区别与应用
引用和指针在C++中都有其独特的优势和应用场景。引用更适合简洁、安全的代码,而指针提供了更大的灵活性和动态内存管理的能力。在实际编程中,根据需求选择适当的类型,能够编写出高效、可维护的代码。理解并正确使用这两种类型,是掌握C++编程的关键一步。
11 1
|
9天前
|
存储 C语言
C语言学习记录——7000+字长文-复习&学习指针(指针、地址、指针变量、指针与数组、指针与函数、指针数组、多级指针)二
C语言学习记录——7000+字长文-复习&学习指针(指针、地址、指针变量、指针与数组、指针与函数、指针数组、多级指针)二
12 1
|
9天前
|
存储 C语言
C语言学习记录——7000+字长文-复习&学习指针(指针、地址、指针变量、指针与数组、指针与函数、指针数组、多级指针)一
C语言学习记录——7000+字长文-复习&学习指针(指针、地址、指针变量、指针与数组、指针与函数、指针数组、多级指针)一
9 1
|
10天前
|
C++
【C++系列】指针对象和对象指针的区别
这段内容介绍了C++中`ListNode`对象和指针的两种使用方式以及它们的区别。首先,`ListNode dummy(0); ListNode* cur = &dummy;创建了一个`ListNode`对象`dummy`在栈上,`cur`是`dummy`的地址。而`ListNode* dummy = new ListNode(0); ListNode* cur = dummy;`则在堆上分配了一个`ListNode`,`dummy`和`cur`都是指向该对象的指针。使用`&dummy`作为虚拟头节点简化链表操作,避免特殊处理。栈分配内存自动管理但生命周期受限,堆分配内存需手动释放且速度较慢。
|
10天前
|
存储 C语言
C语言数组指针和指针数组的区别及使用方法
C语言数组指针和指针数组的区别及使用方法
11 0
|
14天前
|
C++ 存储 Java
C++ 引用和指针:内存地址、创建方法及应用解析
'markdown'C++ 中的引用是现有变量的别名,用 `&` 创建。例如:`string &meal = food;`。指针通过 `&` 获取变量内存地址,用 `*` 创建。指针变量存储地址,如 `string *ptr = &food;`。引用不可为空且不可变,指针可为空且可变,适用于动态内存和复杂数据结构。两者在函数参数传递和效率提升方面各有优势。 ```
|
16天前
|
C++
多重指针:深入解析、应用与示例
多重指针:深入解析、应用与示例
|
16天前
|
C语言
文件类型指针及其在编程中的应用
文件类型指针及其在编程中的应用
15 0
|
15天前
|
C语言
C语言指针带代码
C语言指针带代码
21 3
|
17天前
|
C语言
C语言中返回指针值的函数
C语言中返回指针值的函数
20 0