Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 键入将int数组转换为char指针,并在两个索引的值之间读取_C++_Pointers - Fatal编程技术网

C++ 键入将int数组转换为char指针,并在两个索引的值之间读取

C++ 键入将int数组转换为char指针,并在两个索引的值之间读取,c++,pointers,C++,Pointers,假设内存中有一个整数(每个4字节)数组 memory location: 10 14 18 22 value: [ 1 ][ 2 ][ 3 ][ 4 ] 如果我使用字符指针“p”,如图所示 #include <iostream> using namespace std; int main() { int a[] ={1,2,3,4}; char *p = (char*)a; //character pointer cout&l

假设内存中有一个整数(每个4字节)数组

memory location:  10   14   18   22
value:          [ 1 ][ 2 ][ 3 ][ 4 ]
如果我使用字符指针“p”,如图所示

#include <iostream>
using namespace std;
int main()
{
    int a[] ={1,2,3,4};
    char *p = (char*)a; //character pointer
    cout<<(int)(*(p+0))<<endl;
    cout<<(int)(*(p+1))<<endl; //point A
    cout<<(int)(*(p+2))<<endl;
    cout<<(int)(*(p+4))<<endl;
    return 0;
}
为什么我得到的是0而不是垃圾值(考虑到a点,我们应该得到一个等于[I]的最后3个字节+[1]的第一个字节的整数值)。我只是个初学者,如果我犯了什么愚蠢的错误,我很抱歉

我想做的是让我们

a[0] = 2147483647
a[1] = 2147483646
then in bits 
a[0] = 11111111 11111111 11111111 11111111
a[1] = 11111111 11111111 11111111 11111110
taking a char pointer p = (int*)(&a[0] + 1)
should hold 11111111 11111111 11111111 (<-from a[0], from a[1]->) 11111111
hence (int) *p should be again 2147483647
a[0]=2147483647
a[1]=2147483646
然后一点点
a[0]=11111111111111111111111111111111
a[1]=11111111111111111111111111111111110
获取字符指针p=(int*)(&a[0]+1)
应该保持11111111111111111111111()11111111111
因此(int)*p应再次为2147483647
为什么我得到的是0而不是垃圾值(考虑到a点,我们应该得到一个等于[I]的最后3个字节+[1]的第一个字节的整数值)

因为你写的代码没有做到这一点。您有一个
int
s数组,可以使用char指针访问该数组。所以,
*(p+0)
将为您提供第一个字节<代码>*(p+1)第二个,依此类推。您被强制转换为
int
是不必要的(它只会将结果数字转换为
int
),这样做太晚了。您需要重铸指针值:

std::cout << *(int*)(p+1);
std::cout
为什么我得到的是0而不是垃圾值(考虑到a点,我们应该得到一个等于[I]的最后3个字节+[1]的第一个字节的整数值)

因为你写的代码没有做到这一点。您有一个
int
s数组,可以使用char指针访问该数组。所以,
*(p+0)
将为您提供第一个字节<代码>*(p+1)
第二个,依此类推。您被强制转换为
int
是不必要的(它只会将结果数字转换为
int
),这样做太晚了。您需要重铸指针值:

std::cout << *(int*)(p+1);
std::cout
为什么我得到的是0而不是垃圾值

为什么您认为0不是垃圾值?不能保证垃圾值不是0。0是垃圾的完全有效值

也就是说,你不会打印任何有垃圾价值的东西。数组元素之间没有填充,并且
int
本身不包含填充,并且数组中没有未初始化的对象

int
由一个或多个字节组成。在您的系统上,它正好是4个字节
p+0
指向第一个字节,
p+1
指向第二个字节,
p+4
指向第二个整数的第一个字节。如果第一个字节和第二个字节的值均为0,则整数不可能表示1

在两个索引值之间读取

数组的元素之间没有空格,因此没有可读取的内容。您正在读取数组中元素的不同部分

(考虑A点,我们应该得到一个等于[i]的最后3个字节+[1]的第一个字节的整数值。)

你可以这样做:

int i;
std::memcpy(&i, p + 1, sizeof i);
std::cout << i;
inti;
标准::memcpy(&i,p+1,sizeof i);
标准::cout
为什么我得到的是0而不是垃圾值

为什么您认为0不是垃圾值?不能保证垃圾值不是0。0是垃圾的完全有效值

也就是说,你不会打印任何有垃圾价值的东西。数组元素之间没有填充,并且
int
本身不包含填充,并且数组中没有未初始化的对象

int
由一个或多个字节组成。在您的系统上,它正好是4个字节
p+0
指向第一个字节,
p+1
指向第二个字节,
p+4
指向第二个整数的第一个字节。如果第一个字节和第二个字节的值均为0,则整数不可能表示1

在两个索引值之间读取

数组的元素之间没有空格,因此没有可读取的内容。您正在读取数组中元素的不同部分

(考虑A点,我们应该得到一个等于[i]的最后3个字节+[1]的第一个字节的整数值。)

你可以这样做:

int i;
std::memcpy(&i, p + 1, sizeof i);
std::cout << i;
inti;
标准::memcpy(&i,p+1,sizeof i);

std::cout首先,0是一个完全有效的“垃圾值”

但这在这里是没有意义的,因为您实际上并没有将4个字节转换为整数-您提取一个字节,然后将其转换为整数。您必须将
char*
重新解释为
int*
(然后取消引用)来执行您所说的操作,然后我们得出以下结论:

未定义的行为 像这样操纵内存具有未定义的行为。当您试图假装非
int
int
时,任何事情都可能发生

这不仅仅是标准主义、清教徒主义或学究主义。这是真的,它有现实世界的实际结果,就像你看到的那样

将你用C++语言描述的抽象程序翻译成计算机能理解的真实世界的实际程序是难以置信的复杂。编译器不会一次只处理一行代码,而只是天真地将它们重写为相同的代码,但使用机器语言。它阅读你的全部源代码,理解你想要什么,它向你描述的程序,然后用一种完全不同的、不相关的、独立的语言创建一个全新的程序,它具有相同的结果。要快速做到这一点,还需要一些捷径

当您编写一个行为未定义的程序时,您破坏了这个过程。您不能简单地假设“我们应该得到一个等于[i]的最后3个字节+[1]的第一个字节的整数值”。在20世纪70年代,这种说法可能更为正确,但计算机确实很复杂,现代计算机比古董计算机更为复杂


简短版本:不要这样做。

首先,0是一个完全有效的“垃圾值”

但这在这里是没有意义的,因为你实际上不是