【C语言】深入解开指针(一)2

简介: 【C语言】深入解开指针(一)

【C语言】深入解开指针(一)1:https://developer.aliyun.com/article/1474257

2.2.2 解引⽤操作符

解引用运算符( * ) 将指针变量所指向的对象的值赋给左值变量。当使用指针变量时,使用解引用运算符来访问指针变量所指向的对象。

#include <stdio.h>
int main()
{
  int a = 100;
  int* pa = &a;
  *pa = 0;
  printf("%d", a);
  return 0;
}

*pa 的意思就是通过pa中存放的地址,找到指向的空间,

*pa其实就是a变量了;所以*pa = 0,这个操作符是把a改成了0

#include <stdio.h>

int main()
{
    int num1 = 10;
    int *ptr1 = &num1;

    printf("The value of num1 is %d\n", num1);
    printf("The address of num1 is %d\n", &num1);
    printf("The value of ptr1 is %d\n", ptr1);
    printf("The value of *ptr1 is %d\n", *ptr1);

    return 0;
}

变量 num1 的值为 10,因为它被赋值为 10。

变量 num1 的地址为 13629256,因为它在内存中的位置是 13629256。

变量 ptr1 的值为 13629256,因为它被赋值为 num1 的地址。

变量 *ptr1 的值为 10,因为它是 ptr1 所指向的对象的值。


2.3 指针变量的⼤⼩

指针变量的⼤⼩取决于地址的⼤⼩

• 32位平台下地址是32个bit位,指针变量⼤⼩是4个字节

• 64位平台下地址是64个bit位,指针变量⼤⼩是8个字节

• 注意指针变量的⼤⼩和类型是⽆关的,只要指针类型的变量,在相同的平台下,⼤⼩都是相同的。

32位机器假设有32根地址总线,每根地址线出来的电信号转换成数字信号后是1或者0,那我们把32根地址线产⽣的2进制序列当做⼀个地址,那么⼀个地址就是32个bit位,需要4个字节才能存储。

#include <stdio.h>
int main()
{
  int* a = 10;
  short* b = 10;
  char* c = 10;
  double* d = 10;
  
  printf("%d\n", sizeof(a));
  printf("%d\n", sizeof(b));
  printf("%d\n", sizeof(c));
  printf("%d\n", sizeof(d));
  return 0;
}

debug X86也就是调试状态下的32位环境下:

debug X64也就是调试状态下的64位环境下:

三、 指针变量类型的意义

当你看到这里,你发现指针变量的⼤⼩和类型⽆关,只要是指针变量,在同⼀个平台下,⼤⼩都是⼀样的, 那还要那么多的指针类型干嘛呢?统一归为一种指针类型不就好了,就没那么麻烦了,bug或许可能就没有那么多了!同学带着你的疑问,让我们一起走下去。看看为什么这么设计的?


3.1 指针的解引⽤

首先,我们观察两组代码的变化环境为debug x86

  1. 代码1:
#include <stdio.h>
int main()
{
  int n = 0x66778899;
  int* pk = &n;
  *pk = 0;
  return 0;
}

  1. 代码2:
#include <stdio.h>
int main()
{
  int n = 0x66778899;
  char* pk = (char*)&n;
  *pk = 0;
  return 0;
}

调试我们可以看到,代码1会将n的4个字节全部改为0,但是代码2只是将n的第⼀个字节改为0。

结论:指针的类型决定了,对指针解引⽤的时候有多⼤的权限(⼀次能操作⼏个字节)。

⽐如: char* 的指针解引⽤就只能访问⼀个字节,⽽ int* 的指针的解引⽤就能访问四个字节

3.2 指针+ - 整数

指针加减整数的语法如下:

ptr + n
ptr - n
• 1
• 2

其中,ptr 是指针变量,n 是整数。

当我们向一个指针加减整数时,我们实际上是在向指针所指向的内存地址加减整数。这意味着,如果我们向一个指针加 1,则指针会指向内存中下一个字节的位置。如果我们向一个指针减 1,则指针会指向内存中上一个字节的位置。


以下是不同类型的指针加减整数的示例:

整数指针:

int *p = 0;
p++; // 指向内存中下一个字节的位置
p--; // 指向内存中上一个字节的位置

指针数组:

int arr[] = {1, 2, 3, 4, 5};
int *p = arr;//int*类型加4
p++; // 指向内存中下一个元素的位置
p--; // 指向内存中上一个元素的位置

下是指针加减 1 的示例:

#include <stdio.h>
int main()
{
  int n = 10;
  char* pc = (char*)&n;
  int* pi = &n;
  int* arr[] = { 1,2,3,4,5 };
  int* pk = arr;
  printf("%p\n", &n);
  printf("%p\n", pc);
  printf("%p\n", pc + 1);
  printf("%p\n", pi);
  printf("%p\n", pi + 1);
  printf("%p\n", pk);
  printf("%p\n", pk + 1);
  return 0;
}

运行结果:

可以看到,

char类型的指针变量+1跳过1个字节,int类型的指针变量+1跳过了4个字节。这表明指针变量的类型差异会导致步长的变化。

结论:指针的类型决定了指针向前或向后移动一步的距离。

3.3 void* 指针

void 指针是 C 语言中一种特殊的指针,它可以指向任何类型的数据。void 指针的类型是 void,它不指向任何特定的数据类型。

void* 类型的指针不能直接进⾏指针的±整数和解引⽤的运算。

void 指针也可以用来解引用,但必须在解引用之前使用类型转换。void` 指针可以用来存储指向任何类型数据的指针。

#include <stdio.h>
int main()
{
  int a = 88;
  void* p=&a;
  int* q = (int*)p;//类型转换
  printf("n = %d\n", *q);
  return 0;
}

void* 类型的指针不能直接进⾏指针的±整数和解引⽤的运算。

相关文章
|
8天前
|
存储 人工智能 Java
一文轻松拿捏C语言的指针的基础使用
本文介绍了C语言中的指针概念,包括直接访问和间接访问内存的方式、指针变量的定义与使用、取址运算符`&`和取值运算符`*`的应用,帮助读者深入理解指针这一C语言的核心概念。君志所向,一往无前!
17 0
|
3月前
|
存储 NoSQL 编译器
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
指针是一个变量,它存储另一个变量的内存地址。换句话说,指针“指向”存储在内存中的某个数据。
129 3
【C语言】指针的神秘探险:从入门到精通的奇幻之旅 !
|
3月前
|
存储 编译器 C语言
【C语言】指针大小知多少 ?一场探寻C语言深处的冒险 !
在C语言中,指针的大小(即指针变量占用的内存大小)是由计算机的体系结构(例如32位还是64位)和编译器决定的。
270 9
|
3月前
|
安全 程序员 C语言
【C语言】指针的爱恨纠葛:常量指针vs指向常量的指针
在C语言中,“常量指针”和“指向常量的指针”是两个重要的指针概念。它们在控制指针的行为和数据的可修改性方面发挥着关键作用。理解这两个概念有助于编写更安全、有效的代码。本文将深入探讨这两个概念,包括定义、语法、实际应用、复杂示例、最佳实践以及常见问题。
74 7
|
4月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
4月前
|
算法 C语言
C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项
本文深入讲解了C语言中的文件操作技巧,涵盖文件的打开与关闭、读取与写入、文件指针移动及注意事项,通过实例演示了文件操作的基本流程,帮助读者掌握这一重要技能,提升程序开发能力。
264 3
|
4月前
|
存储 算法 程序员
C 语言指针详解 —— 内存操控的魔法棒
《C 语言指针详解》深入浅出地讲解了指针的概念、使用方法及其在内存操作中的重要作用,被誉为程序员手中的“内存操控魔法棒”。本书适合C语言初学者及希望深化理解指针机制的开发者阅读。
|
4月前
|
程序员 C语言
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门
C语言中的指针既强大又具挑战性,它像一把钥匙,开启程序世界的隐秘之门。本文深入探讨了指针的基本概念、声明方式、动态内存分配、函数参数传递、指针运算及与数组和函数的关系,强调了正确使用指针的重要性,并鼓励读者通过实践掌握这一关键技能。
82 1
|
4月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
4月前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。