指针是C语言的核心特性,深入理解指针对于掌握C语言至关重要。东巴文(db-w.cn) 将带你深入探索指针的本质。
💡 东巴文观点:指针不仅仅是一个地址,它是一个类型化的地址,包含了类型信息和地址信息。
#include <stdio.h>
int main() {
printf("=== 东巴文指针的内存模型 ===\n\n");
int num = 10;
int *ptr = #
printf("变量 num:\n");
printf(" 值: %d\n", num);
printf(" 地址: %p\n", &num);
printf(" 大小: %zu 字节\n", sizeof(num));
printf("\n指针 ptr:\n");
printf(" 值(地址): %p\n", ptr);
printf(" 指向的值: %d\n", *ptr);
printf(" 指针大小: %zu 字节\n", sizeof(ptr));
printf(" 指针的地址: %p\n", &ptr);
return 0;
}
东巴文说明:
#include <stdio.h>
int main() {
printf("=== 东巴文指针的类型 ===\n\n");
int num = 10;
double dbl = 3.14;
char ch = 'A';
int *intPtr = #
double *dblPtr = &dbl;
char *charPtr = &ch;
printf("int指针大小: %zu 字节\n", sizeof(intPtr));
printf("double指针大小: %zu 字节\n", sizeof(dblPtr));
printf("char指针大小: %zu 字节\n", sizeof(charPtr));
printf("\n不同类型指针存储的地址:\n");
printf("intPtr: %p\n", intPtr);
printf("dblPtr: %p\n", dblPtr);
printf("charPtr: %p\n", charPtr);
return 0;
}
东巴文说明:
#include <stdio.h>
int main() {
printf("=== 东巴文指针的基本定义 ===\n\n");
// 方式1:先声明后初始化
int num = 10;
int *ptr1;
ptr1 = #
// 方式2:声明时初始化
int *ptr2 = #
// 方式3:初始化为NULL
int *ptr3 = NULL;
printf("ptr1 = %p, *ptr1 = %d\n", ptr1, *ptr1);
printf("ptr2 = %p, *ptr2 = %d\n", ptr2, *ptr2);
printf("ptr3 = %p\n", ptr3);
return 0;
}
#include <stdio.h>
int main() {
printf("=== 东巴文多指针定义 ===\n\n");
int num1 = 10, num2 = 20, num3 = 30;
// 方式1:分别定义
int *ptr1 = &num1;
int *ptr2 = &num2;
int *ptr3 = &num3;
// 方式2:一行定义多个指针
int *p1 = &num1, *p2 = &num2, *p3 = &num3;
printf("ptr1 = %p, *ptr1 = %d\n", ptr1, *ptr1);
printf("ptr2 = %p, *ptr2 = %d\n", ptr2, *ptr2);
printf("ptr3 = %p, *ptr3 = %d\n", ptr3, *ptr3);
return 0;
}
东巴文说明:
*int *p1, *p2, *p3; 正确int *p1, p2, p3; 错误(p2、p3是int类型,不是指针)#include <stdio.h>
int main() {
printf("=== 东巴文指向基本类型的指针 ===\n\n");
// 整型指针
int intVal = 10;
int *intPtr = &intVal;
// 浮点指针
double dblVal = 3.14;
double *dblPtr = &dblVal;
// 字符指针
char charVal = 'A';
char *charPtr = &charVal;
printf("int指针: *intPtr = %d\n", *intPtr);
printf("double指针: *dblPtr = %.2f\n", *dblPtr);
printf("char指针: *charPtr = %c\n", *charPtr);
return 0;
}
#include <stdio.h>
int main() {
printf("=== 东巴文指向指针的指针 ===\n\n");
int num = 10;
int *ptr = #
int **pptr = &ptr;
printf("num = %d\n", num);
printf("&num = %p\n", &num);
printf("\nptr = %p\n", ptr);
printf("*ptr = %d\n", *ptr);
printf("&ptr = %p\n", &ptr);
printf("\npptr = %p\n", pptr);
printf("*pptr = %p\n", *pptr);
printf("**pptr = %d\n", **pptr);
return 0;
}
东巴文说明:
int *ptr - 指向int的指针int **pptr - 指向int指针的指针**pptr - 二次解引用#include <stdio.h>
int main() {
printf("=== 东巴文void指针 ===\n\n");
int num = 10;
double dbl = 3.14;
// void指针可以指向任何类型
void *vptr1 = #
void *vptr2 = &dbl;
printf("void指针可以指向任何类型:\n");
printf("vptr1 = %p\n", vptr1);
printf("vptr2 = %p\n", vptr2);
// 使用前需要类型转换
int *intPtr = (int *)vptr1;
double *dblPtr = (double *)vptr2;
printf("\n类型转换后:\n");
printf("*intPtr = %d\n", *intPtr);
printf("*dblPtr = %.2f\n", *dblPtr);
return 0;
}
东巴文说明:
void * 是通用指针类型#include <stdio.h>
int main() {
printf("=== 东巴文const指针 ===\n\n");
int num1 = 10;
int num2 = 20;
// 指向常量的指针
const int *ptr1 = &num1;
// *ptr1 = 30; // 错误:不能修改指向的值
ptr1 = &num2; // 正确:可以修改指针本身
// 指针常量
int * const ptr2 = &num1;
*ptr2 = 30; // 正确:可以修改指向的值
// ptr2 = &num2; // 错误:不能修改指针本身
// 指向常量的指针常量
const int * const ptr3 = &num1;
// *ptr3 = 40; // 错误
// ptr3 = &num2; // 错误
printf("ptr1 = %p\n", ptr1);
printf("ptr2 = %p, *ptr2 = %d\n", ptr2, *ptr2);
printf("ptr3 = %p, *ptr3 = %d\n", ptr3, *ptr3);
return 0;
}
东巴文说明:
const int *ptr - 指向常量的指针,不能修改指向的值int * const ptr - 指针常量,不能修改指针本身const int * const ptr - 指向常量的指针常量#include <stdio.h>
void copy(int * restrict dest, const int * restrict src, int n) {
for (int i = 0; i < n; i++) {
dest[i] = src[i];
}
}
int main() {
printf("=== 东巴文restrict指针 ===\n\n");
int src[] = {1, 2, 3, 4, 5};
int dest[5];
copy(dest, src, 5);
printf("复制结果:\n");
for (int i = 0; i < 5; i++) {
printf("dest[%d] = %d\n", i, dest[i]);
}
return 0;
}
东巴文说明:
restrict 关键字表示指针是访问该对象的唯一方式#include <stdio.h>
int main() {
printf("=== 东巴文避免野指针 ===\n\n");
// ❌ 危险:未初始化的指针
// int *ptr; // 野指针
// *ptr = 10; // 错误:可能崩溃
// ✅ 正确:初始化为NULL
int *ptr = NULL;
if (ptr != NULL) {
*ptr = 10;
} else {
printf("指针为NULL,不能解引用\n");
}
return 0;
}
东巴文说明:
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文避免悬空指针 ===\n\n");
int *ptr = (int *)malloc(sizeof(int));
if (ptr != NULL) {
*ptr = 100;
printf("值:%d\n", *ptr);
free(ptr);
// ❌ 危险:释放后继续使用
// printf("%d\n", *ptr); // 悬空指针
// ✅ 正确:释放后置NULL
ptr = NULL;
}
return 0;
}
东巴文说明:
#include <stdio.h>
int main() {
printf("=== 东巴文避免空指针解引用 ===\n\n");
int *ptr = NULL;
// ❌ 危险:解引用空指针
// *ptr = 10; // 错误:程序崩溃
// ✅ 正确:检查NULL
if (ptr != NULL) {
*ptr = 10;
} else {
printf("指针为NULL,不能解引用\n");
}
return 0;
}
#include <stdio.h>
void swap(int *a, int *b) {
int temp = *a;
*a = *b;
*b = temp;
}
int main() {
printf("=== 东巴文指针作为函数参数 ===\n\n");
int num1 = 10, num2 = 20;
printf("交换前:num1 = %d, num2 = %d\n", num1, num2);
swap(&num1, &num2);
printf("交换后:num1 = %d, num2 = %d\n", num1, num2);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文动态内存管理 ===\n\n");
// 动态分配数组
int *arr = (int *)malloc(5 * sizeof(int));
if (arr != NULL) {
// 初始化数组
for (int i = 0; i < 5; i++) {
arr[i] = i * 10;
}
// 输出数组
printf("动态数组:\n");
for (int i = 0; i < 5; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
free(arr);
arr = NULL;
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
// 链表节点
typedef struct Node {
int data;
struct Node *next;
} Node;
int main() {
printf("=== 东巴文指针实现数据结构 ===\n\n");
// 创建链表
Node *head = (Node *)malloc(sizeof(Node));
head->data = 10;
head->next = (Node *)malloc(sizeof(Node));
head->next->data = 20;
head->next->next = NULL;
// 遍历链表
Node *current = head;
printf("链表元素:\n");
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
// 释放内存
while (head != NULL) {
Node *temp = head;
head = head->next;
free(temp);
}
return 0;
}
#include <stdio.h>
int main() {
printf("=== 东巴文始终初始化指针 ===\n\n");
// ✅ 推荐:初始化为NULL
int *ptr1 = NULL;
// ✅ 推荐:初始化为有效地址
int num = 10;
int *ptr2 = #
printf("ptr1 = %p\n", ptr1);
printf("ptr2 = %p, *ptr2 = %d\n", ptr2, *ptr2);
return 0;
}
#include <stdio.h>
void process(int *ptr) {
// ✅ 正确:检查NULL
if (ptr != NULL) {
printf("值:%d\n", *ptr);
} else {
printf("指针为NULL\n");
}
}
int main() {
printf("=== 东巴文使用前检查NULL ===\n\n");
int num = 10;
process(&num);
process(NULL);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文释放后置NULL ===\n\n");
int *ptr = (int *)malloc(sizeof(int));
if (ptr != NULL) {
*ptr = 100;
printf("值:%d\n", *ptr);
free(ptr);
ptr = NULL; // ✅ 正确:释放后置NULL
}
return 0;
}
完成本章学习后,请确认:
掌握指针的概念与定义后,你可以继续学习:
如果遇到问题,欢迎访问 东巴文(db-w.cn) 获取帮助!
东巴文(db-w.cn) - 让编程学习更简单
🎯 东巴文指针提示:深入理解指针的本质和类型系统,是掌握C语言指针的关键。在 db-w.cn,我们会通过大量实例帮你深入理解指针!