「C系列」C 指针及其应用案例

雪梅零落 2024-06-14 13:35:02 阅读 63

文章目录

一、C 指针1. 指针的定义2. 指针的初始化3. 指针的解引用4. 指针的运算5. 动态内存分配6. 指针的NULL初始化7. 指针作为函数参数和返回值8. 指针数组和数组指针9. 多级指针 二、C语言中有哪些内置的指针操作符三、常见应用案例1. 交换两个变量的值2. 数组与指针3. 字符串操作4. 链表操作5. 动态内存分配 四、相关链接

在这里插入图片描述

一、C 指针

在C语言中,指针是一个非常重要的概念,它允许程序直接访问内存地址,并操作该地址上存储的数据。指针本身是一个变量,但它存储的不是实际的数据值,而是存储数据值的内存地址。

以下是关于C语言中指针的一些基本概念和用法:

1. 指针的定义

指针变量通常通过以下方式定义:

int *ptr; // 定义一个指向int类型数据的指针变量ptr

这里的int *是一个类型,表示这是一个指向int类型数据的指针。

2. 指针的初始化

在定义指针变量后,通常需要将其初始化为一个有效的内存地址。这可以通过以下方式完成:

int x = 10;int *ptr = &x; // 将ptr初始化为x的地址

在这里,&是一个取地址运算符,它返回变量x在内存中的地址。

3. 指针的解引用

解引用指针意味着访问指针所指向的内存地址上的数据。这可以通过在指针变量前加*来实现:

int y = *ptr; // 将ptr所指向的int值(即x的值)赋值给y

4. 指针的运算

指针可以进行一些基本的算术运算,如加法、减法等。但这些运算不是基于指针的值(即内存地址),而是基于指针所指向的数据类型的大小。例如,如果ptr是一个指向int的指针,那么ptr + 1将指向下一个int类型的内存位置。

5. 动态内存分配

在C语言中,可以使用malloccalloc等函数在运行时动态地分配内存,并将返回的内存地址存储在指针变量中。例如:

int *array = (int *)malloc(10 * sizeof(int)); // 分配一个包含10个int的数组的内存

注意:在使用完动态分配的内存后,应使用free函数释放内存,以避免内存泄漏。

6. 指针的NULL初始化

为了避免野指针(指向无效内存地址的指针),通常会将指针初始化为NULL:

int *ptr = NULL;

7. 指针作为函数参数和返回值

指针经常作为函数的参数和返回值,以实现数据的间接访问和修改。例如,一个交换两个整数值的函数可以接收两个指向整数的指针作为参数:

void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp;}

8. 指针数组和数组指针

指针数组:一个数组,其元素是指针。数组指针:一个指针,指向数组的首个元素。

这两者在语法和用途上有所不同,需要仔细区分。

9. 多级指针

在C语言中,还可以定义指向指针的指针,即多级指针。例如,int **ptr是一个指向int指针的指针。多级指针在某些复杂的数据结构和算法中非常有用。

二、C语言中有哪些内置的指针操作符

在C语言中,与指针相关的内置操作符主要有以下几个:

取地址操作符(&) 这个操作符用于获取变量的内存地址。示例:int x = 10; int *ptr = &x; 这里,&x 就是取变量 x 的地址,并将这个地址赋值给指针 ptr解引用操作符(*) 这个操作符用于访问指针所指向的内存地址中的数据。示例:int y = *ptr; 这里,*ptr 就是访问 ptr 所指向的内存地址上的数据,并将其赋值给变量 y。当 * 出现在声明中时,它表示指针的类型;但在表达式中,它表示解引用操作。 指针算术操作符(+ 和 -) 这两个操作符用于指针的算术运算。当用于指针时,它们基于指针所指向的数据类型的大小进行运算。例如,对于指向 int 的指针,ptr + 1 会将指针向前移动一个 int 的大小。示例:ptr++ptr += 2 等都是有效的指针算术操作。 指针比较操作符(==、!=、<、<=、>、>=) 这些操作符用于比较两个指针是否指向相同的内存地址,或者它们在内存中的相对位置。需要注意的是,只有当两个指针指向同一数组(或同一块内存区域)中的元素时,比较它们的大小才有意义。 -> 操作符(结构体指针的成员访问) 这个操作符用于通过结构体指针访问结构体的成员。示例:如果 struct_ptr 是一个指向结构体的指针,并且该结构体有一个名为 member 的成员,则可以使用 struct_ptr->member 来访问这个成员。 . 操作符(结构体的成员访问) 虽然这不是一个专门的指针操作符,但在与结构体和指针一起使用时,. 操作符用于通过结构体变量访问其成员。示例:如果 struct_var 是一个结构体变量,并且该结构体有一个名为 member 的成员,则可以使用 struct_var.member 来访问这个成员。

需要注意的是,除了上述操作符之外,还有其他一些操作符(如赋值操作符 =、自增/自减操作符 ++-- 等)也可以与指针一起使用,但它们并不是专门为指针设计的。

三、常见应用案例

C 语言中的指针具有广泛的应用,以下是一些常见的应用案例及其详细代码:

1. 交换两个变量的值

使用指针可以避免使用临时变量来交换两个变量的值。

#include <stdio.h>void swap(int *a, int *b) { int temp = *a; *a = *b; *b = temp;}int main() { int x = 5, y = 10; printf("Before swap: x = %d, y = %d\n", x, y); swap(&x, &y); printf("After swap: x = %d, y = %d\n", x, y); return 0;}

2. 数组与指针

在 C 语言中,数组名实际上是一个指向数组首元素的指针。

#include <stdio.h>void printArray(int *arr, int size) { for (int i = 0; i < size; i++) { printf("%d ", arr[i]); // 也可以使用 *(arr + i) } printf("\n");}int main() { int arr[] = { 1, 2, 3, 4, 5}; int size = sizeof(arr) / sizeof(arr[0]); printArray(arr, size); return 0;}

3. 字符串操作

在 C 语言中,字符串是通过字符数组实现的,而字符串操作经常涉及到指针。

#include <stdio.h>#include <string.h>void concat(char *dest, const char *src) { while (*dest) { // 找到 dest 字符串的末尾 dest++; } while (*src) { // 复制 src 字符串到 dest 的末尾 *dest++ = *src++; } *dest = '\0'; // 添加字符串结束符}int main() { char str1[50] = "Hello, "; char str2[] = "World!"; concat(str1, str2); printf("%s\n", str1); // 输出: Hello, World! return 0;}

4. 链表操作

链表是一种常见的数据结构,它的节点通常通过指针链接在一起。

#include <stdio.h>#include <stdlib.h>typedef struct Node { int data; struct Node *next;} Node;void insert(Node **head, int data) { Node *newNode = (Node *)malloc(sizeof(Node)); newNode->data = data; newNode->next = *head; *head = newNode;}void printList(Node *head) { Node *current = head; while (current != NULL) { printf("%d ", current->data); current = current->next; } printf("\n");}int main() { Node *head = NULL; insert(&head, 1); insert(&head, 2); insert(&head, 3); printList(head); // 输出: 3 2 1 return 0;}

5. 动态内存分配

使用 malloccallocrealloc 等函数在运行时动态地分配和重新分配内存。

#include <stdio.h>#include <stdlib.h>int main() { int *arr = (int *)malloc(5 * sizeof(int)); if (arr == NULL) { printf("Memory allocation failed\n"); return 1; } for (int i = 0; i < 5; i++) { arr[i] = i + 1; } for (int i = 0; i < 5; i++) { printf("%d ", arr[i]); } printf("\n"); free(arr); // 释放内存 return 0;}

四、相关链接

Visual Studio Code下载地址Sublime Text下载地址「C系列」C 简介「C系列」C 基本语法「C系列」C 数据类型「C系列」C 变量及常见问题梳理「C系列」C 常量「C系列」C 存储类「C系列」C 运算符「C系列」C 判断/循环「C系列」C 函数「C系列」C 作用域规则「C系列」C 数组「C系列」C enum(枚举)


声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。