一、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语言中,可以使用malloc和calloc等函数在运行时动态地分配内存,并将返回的内存地址存储在指针变量中。例如: - int *array = (int *)malloc(10 * sizeof(int)); // 分配一个包含10个int的数组的内存
复制代码
注意:在使用完动态分配的内存后,应使用free函数释放内存,以避免内存泄漏。
6. 指针的NULL初始化
为了避免野指针(指向无效内存地址的指针),通常会将指针初始化为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. 动态内存分配
使用 malloc、calloc 和 realloc 等函数在运行时动态地分配和重新分配内存。 - #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(枚举)
|