C++;从int*到void*再到char*的静态转换-你能帮我理解这段代码吗? 我是C++初学者,我对理解一些代码有问题。

C++;从int*到void*再到char*的静态转换-你能帮我理解这段代码吗? 我是C++初学者,我对理解一些代码有问题。,c++,static-cast,C++,Static Cast,我要做一个练习,编写返回int大小的函数,并且不使用sizeof()和重新解释cast。有人给了我解决方案,但我不明白它是如何工作的。你能帮我理解一下吗?代码如下: int intSize() { int intArray[10]; int * intPtr1; int * intPtr2; intPtr1 = &intArray[1]; intPtr2 = &intArray[2]; //Why cast int pointer to void po

我要做一个练习,编写返回
int
大小的函数,并且不使用
sizeof()
重新解释cast
。有人给了我解决方案,但我不明白它是如何工作的。你能帮我理解一下吗?代码如下:

int intSize() {
  int intArray[10];
  int * intPtr1;
  int * intPtr2;

  intPtr1 = &intArray[1];
  intPtr2 = &intArray[2];

  //Why cast int pointer to void pointer?
  void* voidPtr1 = static_cast<void*>(intPtr1);

  //why cast void pointer to char pointer?
  char* charPtr1 = static_cast<char*>(voidPtr1);

  void* voidPtr2 = static_cast<void*>(intPtr2);
  char* charPtr2 = static_cast<char*>(voidPtr2);

  //when I try to print 'charPtr1' there is nothing printed
  //when try to print charPtr2 - charPtr1, there is correct value shown - 4, why?
  return charPtr2 - charPtr1;
}
int intSize(){
int intArray[10];
int*intPtr1;
int*intPtr2;
intPtr1=&intArray[1];
intPtr2=&intArray[2];
//为什么将int指针强制转换为void指针?
void*voidPtr1=静态浇铸(intPtr1);
//为什么将void指针强制转换为char指针?
char*charPtr1=静态_铸造(voidPtr1);
void*voidPtr2=静态浇铸(intPtr2);
char*charPtr2=静态_铸造(voidPtr2);
//当我尝试打印“charPtr1”时,没有打印任何内容
//当尝试打印charPtr2-charPtr1时,显示了正确的值-4,为什么?
返回charPtr2-charPtr1;
}

总而言之,我不明白的是,为什么我们必须将
int*
更改为
void*
,然后更改为
char*
来执行此任务?为什么我们在减去
charPtr2
charPtr1
时会得到结果,但在尝试仅打印
charPtr1
时却没有显示结果?

这是重要的一点:

intPtr1 = &intArray[1];
intPtr2 = &intArray[2];
这将创建两个指向数组中相邻整数的指针。这两个指针之间的距离是您试图检索的整数的大小。然而,指针算法的工作方式是,如果你减去这两个,那么编译器将返回你整数的大小,它总是1

因此,接下来要做的是将这些字符重新转换为字符指针。每个字符(或事实上是)1个字节,因此这两个指针作为字符指针之间的差异将以字节为单位给出答案。这就是为什么你要使用字符指针和减法


至于via
void*
——这是为了避免使用
重新解释cast
。不允许使用
static\u cast
直接从
int*
转换为
char*
,但通过
void*
将删除此限制,因为编译器不再知道它是以
int*
开头的。您也可以只使用C样式转换,
(char*)(intPtr1)

首先,不要在实际代码中这样做。你会摔断你的腿,看起来像个白痴,所有酷孩子都会嘲笑你

话虽如此,它的工作原理如下: 基本思想是int的大小等于int数组中两个元素之间的偏移量(以字节为单位)。数组中的整数是紧密压缩的,因此第二个整数的开头正好在第一个整数的结尾之后:

int* intPtr1 = &intArray[0];
int* intPtr2 = &intArray[1];
这里的问题是,当减去两个int指针时,不会得到以字节为单位的差值,而是以int为单位的差值。因此,
intPtr2-intPtr1
1
,因为它们相距1 int

<>但是我们是C++的,所以我们可以把指针投向任何东西!因此,我们不使用int指针,而是将值复制到char指针,char指针的大小为1字节(至少在大多数平台上是这样)

char*charPtr1=重新解释强制转换(intPtr1);
char*charPtr2=重新解释(intPtr2);
差异
charPtr2-charPtr1
是以字节为单位的大小。指针仍然指向与以前相同的位置(即数组中第二个和第一个int的起始位置),但现在将以
char
的大小计算差异,而不是以
int
的大小计算差异


由于练习不允许重新解释施法,您将不得不使用另一个技巧。您不能直接从
int*
char*
进行
static\u转换。这是C++保护你不做傻事的方法。诀窍是先将其转换为
void*
。您可以将
static\u转换为
void*
的任何指针类型,也可以从
void*
转换为任何指针类型。

请阅读:评论丰富

int intSize()
{
    int intArray[2]; // Allocate two elements. We don't need any more than that.

    /*intPtr1 and intPtr2 point to the addresses of the zeroth and first array elements*/
    int* intPtr1 = &intArray[0]; // Arrays in C++ are zero based
    int* intPtr2 = &intArray[1];

    /*Note that intPtr2 - intPtr1 measures the distance in memory 
      between the array elements in units of int*/

    /*What we want to do is measure that distance in units of char;
      i.e. in bytes since once char is one byte*/

    /*The trick is to cast from int* to char*. In c++ you need to 
      do this via void* if you are not allowed to use reinterpret_cast*/

     void* voidPtr1 = static_cast<void*>(intPtr1);
     char* charPtr1 = static_cast<char*>(voidPtr1);

     void* voidPtr2 = static_cast<void*>(intPtr2);
     char* charPtr2 = static_cast<char*>(voidPtr2);

    /*The distance in memory will now be measure in units of char; 
      that's how pointer arithmetic works*/
    /*Since the original array is a contiguous memory block, the 
      distance will be the size of each element, i.e. sizeof(int) */
     return charPtr2 - charPtr1;
}
int intSize()
{
int intArray[2];//分配两个元素。我们不需要更多的元素。
/*intPtr1和intPtr2指向第0个和第一个数组元素的地址*/
INT*INTRT1=和INTARTRAY(0);// C++中的数组是零基的
int*intPtr2=&intArray[1];
/*注意,intPtr2-intPtr1测量内存中的距离
以int为单位的数组元素之间*/
/*我们要做的是以字符为单位测量距离;
i、 e.以字节为单位,因为once char是一个字节*/
*技巧是从int *到char *。在C++中,你需要
如果不允许使用reinterpret_cast,请通过void*执行此操作*/
void*voidPtr1=静态浇铸(intPtr1);
char*charPtr1=静态_铸造(voidPtr1);
void*voidPtr2=静态浇铸(intPtr2);
char*charPtr2=静态_铸造(voidPtr2);
/*内存中的距离现在将以字符为单位测量;
指针算法就是这样工作的*/
/*由于原始数组是连续内存块,因此
距离将是每个元素的大小,即sizeof(int)*/
返回charPtr2-charPtr1;
}

在C++中指针减法给出了元素之间的元素个数。 这个指针指向物体。换句话说,
intPtr2-intPtr1
将返回这两个指针之间的
int
数。 程序想知道字节数(
char
),因此 将
int*
转换为
char*
。显然,作者没有 要使用
重新解释强制转换
也可以。和
static\u cast
will 不允许从
int*
直接转换为
char*
,因此 通过
void*
(这是允许的)

说了这么多:从函数名和 指针实际上是如何初始化的,一个简单得多的方法 实施这项工作
int intSize()
{
    int intArray[2]; // Allocate two elements. We don't need any more than that.

    /*intPtr1 and intPtr2 point to the addresses of the zeroth and first array elements*/
    int* intPtr1 = &intArray[0]; // Arrays in C++ are zero based
    int* intPtr2 = &intArray[1];

    /*Note that intPtr2 - intPtr1 measures the distance in memory 
      between the array elements in units of int*/

    /*What we want to do is measure that distance in units of char;
      i.e. in bytes since once char is one byte*/

    /*The trick is to cast from int* to char*. In c++ you need to 
      do this via void* if you are not allowed to use reinterpret_cast*/

     void* voidPtr1 = static_cast<void*>(intPtr1);
     char* charPtr1 = static_cast<char*>(voidPtr1);

     void* voidPtr2 = static_cast<void*>(intPtr2);
     char* charPtr2 = static_cast<char*>(voidPtr2);

    /*The distance in memory will now be measure in units of char; 
      that's how pointer arithmetic works*/
    /*Since the original array is a contiguous memory block, the 
      distance will be the size of each element, i.e. sizeof(int) */
     return charPtr2 - charPtr1;
}
int
intSize()
{
    return sizeof( int );
}
#include <limits>

int intSize()
{
   // digits returns non-sign bits, so add 1 and divide by 8 (bits in a byte)
   return (std::numeric_limits<int>::digits+1)/8;
}