一篇搞定C指针——C指针基础及进阶

目录

1.指针的概念

2.指针的声明

3.指针的初始化

4.指针的使用

(1)指针变量的赋值

(2)指针的解引用操作

5.指针的运算

6.指针数组

7.指向指针的指针

8.指针与数组的关系

9.指针和函数的关系

10.指针的注意事项

11.常量指针和指针常量

12.void指针

13.空指针

14.指针数组

15.数组指针

作为一名程序员,指针是必须掌握的概念之一。在C语言中,指针是一个非常重要的概念,它可以使程序更加灵活和高效。在本篇博客中,我将详细介绍指针在C语言中的概念和使用方法。

1.指针的概念

在C语言中,指针是一种变量类型,它可以存储一个变量的内存地址。指针变量本身也是一个变量,它存储的是一个地址值,而不是实际的数据值。指针变量可以通过解引用操作来访问存储在其地址中的数据。

2.指针的声明

指针的声明需要指定指针类型和指针变量名。指针类型指定了指针所指向的变量类型。例如,int *ptr声明了一个指向int类型变量的指针变量ptr。指针变量名可以任意指定,注意指针声明后要初始化,未初始化的指针,指针指向的地址是任意的,这是非常非常危险的行为,如果刚好指向了,之前使用的地址,你又解引用修改了这个指针的值,可能导致程序不符合预期甚至崩溃,对于一开始不知道初始化为什么值的指针,可以初始化为NULL,例如,int *ptr=NULL。

3.指针的初始化

指针变量需要被初始化,才能使用。指针变量的初始化可以通过以下方式进行:

(1)将指针变量初始化为NULL,表示指针没有指向任何有效的内存地址。例如,int *ptr = NULL。

(2)将指针变量初始化为一个已知的地址。例如,int a = 10; int *ptr = &a;将指针变量ptr初始化为变量a的地址。

4.指针的使用

指针的使用包括指针变量的赋值和解引用操作。

(1)指针变量的赋值

可以通过以下方式为指针变量赋值:

int a = 10;
int *ptr = &a;

以上代码将指针变量ptr初始化为变量a的地址。

(2)指针的解引用操作

指针的解引用操作可以获取指针变量所指向的变量的值。例如,*ptr就是指针变量ptr所指向的变量的值。

int a = 10;
int *ptr = &a;
printf("%d\n", *ptr); // 输出10

5.指针的运算

指针可以进行一些运算,如加法和减法。指针的加法和减法操作的结果是一个新的指针,指向加减后的内存地址

例如,因为ptr为int型的指针,ptr+1表示指针ptr向后移动一个int类型长度(4个字节)的内存地址,即指向下一个int类型变量的地址。同理如果为char 声明的指针,ptr+1表示指针ptr向后移动一个char类型长度(1个字节)的内存地址,即指向下一个char类型变量的地址。

6.指针数组

指针数组是一个包含指针变量的数组。每个指针变量都指向一个变量的地址。指针数组可以用来处理多个变量。

例如,以下代码定义了一个包含3个指针变量的指针数组,每个指针变量都指向一个int类型的变量。

int a =10;
int b = 20;
int c = 30;
int *ptr_arr[3] = {&a, &b, &c};

可以通过以下方式访问指针数组中的元素:

printf("%d\n", *ptr_arr[0]); // 输出a的值,即10

printf("%d\n", *ptr_arr[1]); // 输出b的值,即20

printf("%d\n", *ptr_arr[2]); // 输出c的值,即30

7.指向指针的指针

指向指针的指针是指一个指针变量存储的是另一个指针变量的地址。例如,int **pptr表示pptr指向一个指针变量,这个指针变量指向一个int类型变量的地址

int a = 10;

int *ptr = &a;

int **pptr = &ptr;

printf("%d\n", **pptr); // 输出a的值,即10

8.指针与数组的关系

在C语言中,数组名本质上是一个指向数组第一个元素的指针。因此,可以用指针来访问数组元素。例如,a[i]等价于*(a+i)。

int a[5] = {1, 2, 3, 4, 5};
int *ptr = a; // 将数组名a赋值给指针变量ptr
for(int i=0; i<5; i++){
printf("%d ", *(ptr+i)); // 输出数组元素
}

以上代码将输出数组a中的所有元素。

9.指针和函数的关系

指针在函数中的使用非常广泛。指针可以作为函数的参数传递,也可以作为函数的返回值。

例如,以下代码定义了一个函数swap,用来交换两个int类型变量的值。函数使用了指针作为参数,以实现交换操作

void swap(int *ptr1, int *ptr2){
int temp = *ptr1;
*ptr1 = *ptr2;
*ptr2 = temp;
}

可以通过以下方式调用swap函数:

int a = 10;
int b = 20;
swap(&a, &b);

以上代码将交换变量a和变量b的值。

10.指针的注意事项

在使用指针时需要注意以下几点:

(1)指针变量需要初始化后才能使用。

(2)指针变量需要指向有效的内存地址,否则会导致程序崩溃。

(3)指针变量解引用时需要注意指针指向的数据类型和大小。

(4)指针运算时需要注意指针指向的数据类型和大小,防止越界访问。

(5)指针的生命周期需要注意,防止使用已被销毁的指针。

================================================

   进阶内容

11.常量指针和指针常量

常量指针和指针常量是两种不同类型的指针,它们都具有一定的限制。

常量指针(const pointer)是指针指向的内存区域的值不可改变,但指针本身可以改变。这意味着,可以使用常量指针来避免意外修改指向的数据。例如:

int x = 5;
const int *p = &x; // p是指向常量的指针,指向x的地址
*p = 7; // 错误:不能通过常量指针修改所指向的内存
int y = 6;
p = &y; // 正确:可以改变指针p的指向,使其指向y

指针常量(pointer const)是指针本身的值不可改变,但指针所指向的内存区域的值可以改变。这意味着,可以使用指针常量来防止指针被意外地修改。例如:

int x = 5;
int *const p = &x; // p是指针常量,指向x的地址
*p = 7; // 正确:可以通过指针常量修改所指向的内存
int y = 6;
p = &y; // 错误:不能改变指针p的指向

对于这个不理解的可以,看我前一篇还是两篇博客,其中详细介绍了const对于变量和指针的修饰效果和如何记忆区分。

12.void指针

void指针是一种特殊类型的指针,它可以指向任何类型的数据,但不能直接访问指向的数据。需要在使用时,将其强制类型转换为正确的指针类型。例如:

int i = 10;
float f = 3.14;
void *p; // 定义一个void指针
p = &i; // 将p指向i的地址
printf("%d\n", *(int*)p); // 使用强制类型转换将void指针转换为int指针,并输出所指向内存的值
p = &f; // 将p指向f的地址
printf("%f\n", *(float*)p); // 使用强制类型转换将void指针转换为float指针,并输出所指向内存的值

需要注意的是,void指针只能用于指向数据的地址,而不能进行指针运算。

13.空指针

空指针(null pointer)是指一个不指向任何内存地址的指针,也就是说,它指向了一个不存在的内存地址。在C语言中,空指针可以用一个特殊的值NULL来表示。例如:

int *p = NULL; // p是一个空指针
if (p == NULL) {
    printf("p指向的内存地址不存在。\n");
}

使用空指针可以避免指针变量未初始化时指向任意内存地址的问题。需要注意的是,使用空指针访问所指向的内存是非法的,并且可能导致程序崩溃。因此,在使用指针时,需要确保指针不是空指针。

14.指针数组

指针数组是一个数组,其中每个元素都是指针类型。例如:

int a = 1, b = 2, c = 3;
int *p[] = {&a, &b, &c}; // 定义一个指针数组,每个元素都是int类型的指针
for (int i = 0; i < 3; i++) {
    printf("%d\n", *p[i]); // 输出每个指针指向的值
}

指针数组可以用于存储一组指针,每个指针可以指向不同的内存地址。

15.数组指针

数组指针是指向数组的指针,它可以用于访问数组中的元素。例如:

int a[3][2] = {{1, 2}, {3, 4}, {5, 6}};
int (*p)[2] = a; // 定义一个指向数组a的指针
for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 2; j++) {
        printf("%d ", *(*(p+i)+j)); // 输出数组中每个元素的值
    }
    printf("\n");
}

数组指针也可以用于作为形参传递数组,以及在函数中定义动态数组等。

总结

指针是C语言中非常重要的概念,对于理解和操作内存具有关键作用。需要注意的是,在使用指针时,需要注意指针的正确使用和防止指针悬挂等问题。同时,可以使用常量指针、指针常量、void指针、空指针、指针数组和数组指针等来扩展指针的功能。最后能不能看在博主这么幸苦的份上点个关注,点个关注,不迷路。

  • 23
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 23
    评论
评论 23
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值