2023-4-27-深入理解C++指针类型间强制转换

简介: 2023-4-27-深入理解C++指针类型间强制转换

在编程的过程中遇到了很深入的指针之间转换操作,指针的位操作,让我很蒙,这篇文章系统深入的学习一下C++指针类型之间的强制转换,直到学明白为止。

学习后的成果:

char *a="asdasd";
double b= *(double *)&a[0];
• 1
• 2

这段代码虽然只有两句,但并不简单,第一行声明一个char *指针,第二行的意思是

  • a[0] 该字符串第一个元素
  • &a[0] 该字符串第一个元素的地址,这里相当于char * x = &a[0]
  • (double ) &a[0] 将该char指针转换为double *指针 ,相当于double y=(double ) x;
    转换前指针是char
    类型,编译器会找到指针所指向的地址,并每一次取一个字节(char类型元素的大小)将取出来的值按照char类型读取出来;转换后指针是double
    类型,编译器会找到指针所指向的地址,并每一次取八个字节(double类型元素的大小)将取出来的值按照double类型读取出来
  • *(double *)&a[0] 也就是上面所说,取八个字节(double类型元素的大小)将取出来的值按照double类型读取出来


😉一、不同操作系统的基础类型大小

基础类型 32位 64位
bool 1 1
char 1 1
unsigned char 1 1
short int 2 2
int 4 4
指针 4 8
unsigned int 4 4
float 4 4
long 4 4
unsigned long 4 4
double 8 8
long long 8 8

🐱‍🐉二、内存中的地址

地址的本质就是一串01机器代码

内存中的地址没有明确数据类型,但地址值有类型

无论什么类型的指针变量,在内存中本质都是一样的,是一个整数值的地址值。


🎉三、内存中的地址没有明确数据类型,但地址值有类型

int *a;

指针变量,本质上是一个变量,只是它是存放地址的变量,指针的类型代表的是它所指向的变量的类型。因此就有了指向整型、字符型、浮点型等其它类型的指针,但实际上所有类型的指针变量存放的都是int型(某一个地址)。

上述代码表示指向整型的指针变量a,其中a表示一个地址值,上面曾提到地址没有明确的数据类型,因为地址可以为指向整型的指针,可以为指向浮点型的指针。指针类型为整型,表示当我们对该地址进行访问(解引用)时,编译器会将它解释为整型。

注意:指针地址只指向数据存储的内存的位置,具体变量的类型由编译器告知。


🐱‍🚀四、强制转换的原理

(1)普通变量强转

  (float)a,就是先按照int类型取出该数值,再将该数值按照int to float的规则转换成float型,如果反过来,则会发生数据截断。

(2)指针变量强转

  旧指针 to 新指针的强制类型转换是指将指针所指的内容的类型由原先的类型转换为后面的类型:即进行变量解释的时候,解释的类型变化。

  如果有一个指针p,我们需要把它的类型和所指向的类型改为TYEP和TYPE,那么语法格式是:(TYPE)p;这样强制类型转换的结果是一个新指针,该新指针的类型是TYPE*,它指向的类型是TYPE,(也就是说,新指针指向的数据将会用TYPE类型进行解释,如果之前是浮点型数据-3.75,先将其转换为二进制代码,然后转化为TYPE类型存储),它指向的地址就是原指针指向的地址。


🎂五、char*的打印问题!

1.如果给cout提供一个指针,它将打印指针所指向的地址单元的地址,但如果指针类型为char *,则cout将打印char *指针所指向的字符串。

2.如果要显示char *指针所指向的地址单元的地址,需要将char *类型的指针强制转化为另一种类型的指针,我将char *类型的指针强制转化为int *类型指针。

#include "iostream"
#include "regex"
using namespace std;
int main() {
    char  *lpUnitPara = "2111111111111";//lpUnitPara指向字符串的首地址
    std::cout << *lpUnitPara << std::endl;// 2 打印首地址的值
    std::cout << lpUnitPara[0] << std::endl;// 2 打印第一个元素的值
    std::cout << lpUnitPara[1] << std::endl;// 1 打印第二个元素的值
    std::cout << &lpUnitPara<< std::endl; //000000061B10F738 打印的是lpUnitPara指针的地址
    std::cout << lpUnitPara<< std::endl;//2111111111111 lpUnitPara是字符串的首地址,cout会直接打印lpUnitPara指向的字符串
    std::cout << &(lpUnitPara[0]) << std::endl;//2111111111111 lpUnitPara[0]是字符串第一个元素的值,加上&变成了一个char*指针指向第一个元素地址,cout会直接打印该地址指向的字符串
    std::cout << &(lpUnitPara[1]) << std::endl;//111111111111 lpUnitPara[1]是字符串第二个元素的值,加上&变成了一个char*指针指向第二个元素地址,cout会直接打印该地址指向的字符串
    return 0;
}

🥩六、交作业

char *a="asdasd";
double b= *(double *)&a[0];

这段代码虽然只有两句,但并不简单,第一行声明一个char *指针,第二行的意思是

  • a[0] 该字符串第一个元素
  • &a[0] 该字符串第一个元素的地址,这里相当于char * x = &a[0]
  • (double ) &a[0] 将该char指针转换为double *指针 ,相当于double y=(double ) x;
    转换前指针是char
    类型,编译器会找到指针所指向的地址,并每一次取一个字节(char类型元素的大小)将取出来的值按照char类型读取出来;转换后指针是double
    类型,编译器会找到指针所指向的地址,并每一次取八个字节(double类型元素的大小)将取出来的值按照double类型读取出来
  • *(double *)&a[0] 也就是上面所说,取八个字节(double类型元素的大小)将取出来的值按照double类型读取出来

🧊文章总结

提示:这里对文章进行总结:

  大彻大悟


目录
相关文章
|
12天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
35 4
|
27天前
|
存储 安全 编译器
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。
|
1月前
|
存储 C++
c++的指针完整教程
本文提供了一个全面的C++指针教程,包括指针的声明与初始化、访问指针指向的值、指针运算、指针与函数的关系、动态内存分配,以及不同类型指针(如一级指针、二级指针、整型指针、字符指针、数组指针、函数指针、成员指针、void指针)的介绍,还提到了不同位数机器上指针大小的差异。
38 1
|
1月前
|
存储 编译器 C语言
C++入门2——类与对象1(类的定义和this指针)
C++入门2——类与对象1(类的定义和this指针)
30 2
|
1月前
|
存储 编译器 程序员
C++类型参数化
【10月更文挑战第1天】在 C++ 中,模板是实现类型参数化的主要工具,用于编写能处理多种数据类型的代码。模板分为函数模板和类模板。函数模板以 `template` 关键字定义,允许使用任意类型参数 `T`,并在调用时自动推导具体类型。类模板则定义泛型类,如动态数组,可在实例化时指定具体类型。模板还支持特化,为特定类型提供定制实现。模板在编译时实例化,需放置在头文件中以确保编译器可见。
32 11
|
1月前
|
存储 安全 编译器
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值(一)
【C++】C++特性揭秘:引用与内联函数 | auto关键字与for循环 | 指针空值
|
1月前
|
C语言 C++
【C语言】指针篇-一篇搞定不同类型指针变量-必读指南(3/5)
【C语言】指针篇-一篇搞定不同类型指针变量-必读指南(3/5)
|
1月前
|
存储 C++ 索引
C++函数指针详解
【10月更文挑战第3天】本文介绍了C++中的函数指针概念、定义与应用。函数指针是一种指向函数的特殊指针,其类型取决于函数的返回值与参数类型。定义函数指针需指定返回类型和参数列表,如 `int (*funcPtr)(int, int);`。通过赋值函数名给指针,即可调用该函数,支持两种调用格式:`(*funcPtr)(参数)` 和 `funcPtr(参数)`。函数指针还可作为参数传递给其他函数,增强程序灵活性。此外,也可创建函数指针数组,存储多个函数指针。
|
2月前
|
编译器 C++
【C++核心】指针和引用案例详解
这篇文章详细讲解了C++中指针和引用的概念、使用场景和操作技巧,包括指针的定义、指针与数组、指针与函数的关系,以及引用的基本使用、注意事项和作为函数参数和返回值的用法。
41 3
|
1月前
|
算法 C++
【算法】双指针+二分(C/C++
【算法】双指针+二分(C/C++
下一篇
无影云桌面