指针基础

打印 上一主题 下一主题

主题 995|帖子 995|积分 2985

指针

指针

指针是计算机编程中一个紧张的概念,它是一种特殊的数据类型,用于存储变量的内存地点。简单来说,指针指向了一个变量在计算机内存中的存储位置。
每个变量在内存中都有一个地点,在编程中,通过定义指针变量,我们可以存储一个变量的地点,这就使得我们可以通过间接的方式操作和修改变量,而不必要访问原始的变量名。

指针的定义和使用

指针也是一种数据类型,指针变量也是一种变量,指针变量指向谁,就把谁的地点赋值给指针变量。
首先,要声明一个指针变量,必要使用星号"*"来表现该变量是一个指针。
  1. // 关于 * 的位置没有要求,根据个人喜好书写即可
  2. int *ptr;
  3. int* ptr;
  4. int * ptr;
  5. int*ptr;
复制代码
要将指针指向一个变量的内存地点,必要使用取地点符号"&"
  1. int num = 10;
  2. ptr = # // 将ptr指向num的内存地址
复制代码
要访问指针指向的变量的值,必要使用星号"*"来解引用指针。解引用操作符告诉编译器去访问指针所指向的内存地点,并获取那个地点处存储的值。
还可以通过指针来修改变量的值。通过解引用指针并使用赋值操作符,可以将新的值存储到指针指向的内存地点处。
  1. printf("%d", *ptr); // 输出指针所指向的变量的值
  2. *ptr = 20; // 将指针所指向的变量的值修改为20
复制代码
测试程序
  1. #include <stdio.h>
  2. int main()
  3. {
  4.     int a = 9;
  5.     char b = 97;
  6.     printf("%p, %p\n", &a, &b); //打印a, b的地址
  7.     // int *代表是一种数据类型,int*指针类型,p才是变量名
  8.     // 定义了一个指针类型的变量,可以指向一个int类型变量的地址
  9.     int* p;
  10.     //将a的地址赋值给变量p,p也是一个变量,值是一个内存地址编号
  11.     p = &a;
  12.     printf("*p:%d, p:%p\n", *p, p);//p指向了a的地址,*p就是a的值
  13.     char* p1 = &b;
  14.     printf("*p1:%c, p1:%p\n", *p1, p1);//*p1指向了b的地址,*p1就是b的值
  15.     return 0;
  16. }
复制代码
输出效果如下:
  1. 0x7ffdf9863194, 0x7ffdf9863193
  2. *p:9, p:0x7ffdf9863194
  3. *p1:a, p1:0x7ffdf9863193
复制代码
指针巨细

指针是一个变量,它存储了内存地点的值。指针的巨细指的是指针变量指向的存储地点的巨细。在32位平台,所有的指针(地点)都是32位(4字节)。在64位平台,所有的指针(地点)都是64位(8字节)。
  1. #include <stdio.h>
  2. int main()
  3. {
  4.     int* p1;
  5.     int** p2;
  6.     char* p3;
  7.     char** p4;
  8.     printf("sizeof(p1) = %zd\n", sizeof(p1));
  9.     printf("sizeof(p2) = %zd\n", sizeof(p2));
  10.     printf("sizeof(p3) = %zd\n", sizeof(p3));
  11.     printf("sizeof(p4) = %zd\n", sizeof(p4));
  12.     printf("sizeof(double *) = %zd\n", sizeof(double*));
  13.   return 0;
  14. }
  15. /*本地设备现在一般都是64位平台,所以说出结果
  16. sizeof(p1) = 8
  17. sizeof(p2) = 8
  18. sizeof(p3) = 8
  19. sizeof(p4) = 8
  20. sizeof(double *) = 8
  21. */
复制代码
野指针

指针变量也是变量,是变量就可以任意赋值,不要越界即可。但是,任意数值赋值给指针变量没故意义,因为这样的指针就成了野指针,此指针指向的地区是未知(操作体系不答应操作此指针指向的内存地区)。以是,野指针不会直接引发错误,操作野指针指向的内存地区才会出问题。
造成野指针的原因:

  • 指针未初始化
  • 指针越界
  • 指针指向的空间被释放
规避野指针的方法:

  • 指针初始化
  • 制止指针越界
  • 指针指向空间释放实时置NULL
  • 制止返回局部变量的地点
  • 指针使用之前检查有用性
空指针

空指针,就是值为 0 的指针。(任何程序数据都不会存储在地点为 0 的内存块中 ,它是被操作系 统预留的内存块。)
  1. int *p = 0;
  2. int *p = NULL;
复制代码
NULL是一个值为0的宏常量
  1. #define NULL ((void *)0)
复制代码
万能指针void*

void* 是一个特殊的指针类型,用来表现一个指向未知类型的指针。它可以存储任何类型的地点,但无法直接解引用或操作其指向的数据。
它可以用于在没有明白类型信息的情况下表现指针。比方,当你必要在函数中传递一个指针,但不确定指针所指向的数据类型时,可以使用 void* 作为参数类型。
使用 void* 类型时,必要注意的是,在使用 void* 指针进行操作之前,必须将其转换为适当的指针类型,以便进行精确的解引用和操作。这是因为  void* 指针在不确定指向的具体类型时无法进行类型推断。
  1. #include <stdio.h>
  2. int main()
  3. {
  4.     void* p = NULL;
  5.     int a = 10;
  6.     // 指向变量时,最好转换为void *
  7.     p = (void*)&a;
  8.     //使用指针变量指向的内存时,转换为int *
  9.     *((int*)p) = 11;
  10.     //*p = 11;  //这里会编译错误 error: invalid use of void expression
  11.     printf("a = %d\n", a);
  12.     return 0;
  13. }
复制代码
const与指针

在定义指针的时间可以添加const关键字, 根据const关键字的位置可以用其修饰指针本身也可以用来修饰指针指向的值。
常量指针

常量指针:const 关键字在 * 左边,常量指针的本质是指针,表现指针所指向的地点可变,但是地点中的数据不能被修改
  1. const int* ptr;  // ptr 是一个指向 int 类型常量的指针
  2. int const *ptr;  // 等价于 const int* ptr;
复制代码
这里的const是用于修饰*p的,意味着*p是常量,而不是p本身。因此,下面的操作是答应的:
  1. int a = 10;
  2. int b = 20;
  3. const int *p = &a; // p是一个指向整型常量的指针,初始化指向a
  4. p = &b;           // p改变了指向,现在指向b,这是允许的
复制代码
以下操作是不答应的:
  1. *p = 30; // 错误:不能通过p修改它所指向的数据
复制代码
指针常量

const 关键字在 * 右边,表现指针指向的地点不能被修改,但是地点中的值可以被修改。
  1. int a = 10;
  2. int *const p = &a; // p是一个指针常量,初始化指向a
复制代码
在上面的声明中,const关键字修饰的是p,而不是*p,这表明指针p的地点是一个常量,不能改变。
  1. *p = 20; // 允许:通过指针p修改它所指向的数据a的值
复制代码
以下操作不答应:
  1. p = &b; // 错误:p是一个指针常量,不能改变其指向
复制代码
常量指针指向常量数据

当我们在C或C++中使用一个常量指针指向常量数据时,这意味着指针本身和它所指向的数据都不能被修改。这种用法通常用于保护数据不被意外修改,确保数据的完整性。比如:
  1. const int* const p = &a;
复制代码
以下操作都是不答应的:
  1. *p = 10; // 错误:不能通过p修改它所指向的数据
  2. p = &b; // 错误:不能改变p的指向
复制代码
测试程序
  1. #include <stdio.h>
  2. int main()
  3. {
  4.     // 常量指针
  5.     int value1 = 100;
  6.     int value2 = 200;
  7.     const int* ptr = &value1;   // 初始化
  8.     ptr = &value2;  // ok, 可以修改指针指向的内存地址
  9.     //*ptr = 300;     // error, 不能修改指针指向的地址中的值
  10.     // 指针常量
  11.     int value = 10;
  12.     int* const ptr1 = &value;   // 初始化
  13.     *ptr1 = 20;     // ok, 可以修改指针指向的地址中的值
  14.     //ptr1 = &value1; // error, 不能修改指针指向的内存地址
  15.     // 指向常量的指针常量
  16.     const int* const ptr2 = &value2;
  17.     //*ptr2 = 99;     // error, 不能修改指针指向的地址中的值
  18.     //ptr2 = &value;  // error, 不能修改指针指向的内存地址
  19.     return 0;
  20. }
复制代码
引用

C语言之指针篇【超具体讲解,带你层层深入理解指针】_c语言指针-CSDN博客
内存和指针 | 爱编程的大丙
C++学习day--16 野指针和空指针-CSDN博客
C/C++学习-常量指针&指针常量_常量指针和指针常量-CSDN博客

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

科技颠覆者

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表