【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* 类型的指针不能直接进⾏指针的±整数和解引⽤的运算。

相关文章
|
1天前
|
存储 编译器 C语言
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose(下)
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose
7 0
|
1天前
|
C语言
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose(中)
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose
8 0
|
1天前
|
存储 数据库 C语言
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose(上)
C语言进阶⑱(文件上篇)(动态通讯录写入文件)(文件指针+IO流+八个输入输出函数)fopen+fclose
8 0
|
1天前
|
C语言
C语言进阶⑬(字符串函数)+(指针编程题)strlen+strcpy+strcat+strstr+strtok+strerror(下)
C语言进阶⑬(字符串函数)+(指针编程题)strlen+strcpy+strcat+strstr+strtok+strerror
5 0
|
1天前
|
安全 C语言
C语言进阶⑬(字符串函数)+(指针编程题)strlen+strcpy+strcat+strstr+strtok+strerror(中)
C语言进阶⑬(字符串函数)+(指针编程题)strlen+strcpy+strcat+strstr+strtok+strerror
10 0
|
1天前
|
C语言
C语言进阶⑬(字符串函数)+(指针编程题)strlen+strcpy+strcat+strstr+strtok+strerror(上)
C语言进阶⑬(字符串函数)+(指针编程题)strlen+strcpy+strcat+strstr+strtok+strerror
9 0
|
1天前
|
算法 C语言
C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)(下)
C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)
5 0
|
1天前
|
C语言
C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)(中)
C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)
11 0
|
1天前
|
C语言
C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)(上)
C语言进阶⑫(指针下)(指针和数组笔试题解析)(杨氏矩阵)
11 0
|
1天前
|
编译器 C语言
C语言进阶⑪(指针上)(知识点和对应练习)回调函数模拟实现qsort。(下)
C语言进阶⑪(指针上)(知识点和对应练习)回调函数模拟实现qsort。
7 0