Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.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++ 为什么变量指针包含相同数据类型的地址?_C++_C_Pointers_Memory_Memory Address - Fatal编程技术网

C++ 为什么变量指针包含相同数据类型的地址?

C++ 为什么变量指针包含相同数据类型的地址?,c++,c,pointers,memory,memory-address,C++,C,Pointers,Memory,Memory Address,指针声明的一般语法:数据类型*指针\u名称 指针是一个变量,其值是另一个变量的地址,即内存位置的直接地址。与任何变量或常量一样,必须先声明指针,然后才能使用它存储任何变量地址。指针的数据类型必须与指针所指向的变量相同 为什么指针变量应该包含相同数据类型的变量的地址很重要 由于指针与另一个变量的值无关,为什么整数指针不能具有浮点数据类型变量的地址 正确形式: INTA=10 int*ptr=&a 错误,类型不匹配 浮动a int*ptr;ptr=&a 因为当你增加一个指针时 ptr++; 它将指

指针声明的一般语法:
数据类型*指针\u名称

指针是一个变量,其值是另一个变量的地址,即内存位置的直接地址。与任何变量或常量一样,必须先声明指针,然后才能使用它存储任何变量地址。指针的数据类型必须与指针所指向的变量相同

为什么指针变量应该包含相同数据类型的变量的地址很重要

由于指针与另一个变量的值无关,为什么整数指针不能具有浮点数据类型变量的地址

正确形式:

INTA=10

int*ptr=&a

错误,类型不匹配

浮动a

int*ptr;ptr=&a


因为当你增加一个指针时

ptr++;
它将指向与数据类型大小相乘的地址。如果你这样做

ptr+=2;
数据类型占用4个字节,如果指针声明为

float *ptr;

指针将增加8个字节的位置。

指针可以指向任何数据类型:这正是
void
指针的用途。您可以使用
void*
指向任何数据类型1,然后可以将原始指针取回来

float f = 1.0f;
int i = 12;

void *p = &f;
p = &i;
当然,如果不先将
void
指针转换回正确的指针类型,则无法取消引用该指针。由您来确保指针类型是正确的

// In C, this is valid: implicit conversions to void * and back.
float f = 1.0f;
void *p = &f;
float *fp = p;
printf("*fp = %f\n", *fp);

// In C++, you have to use a cast:
float *fp = static_cast<float *>(p);
//在C中,这是有效的:隐式转换为void*并返回。
浮动f=1.0f;
无效*p=&f;
浮点*fp=p;
printf(“*fp=%f\n”,*fp);
//在C++中,必须使用CAST:
浮动*fp=静态_铸造(p);
无效指针有一些限制:不能取消引用它们,也不能执行任何指针算术


1:函数指针不应强制转换为
void*

这是一项安全功能。一种类型的指针指向另一种类型的变量会导致灾难;它几乎没有合法的用途,而且你用它做的任何事情都是危险的,尤其是当类型大小不同时


可以通过强制转换来替代此功能。如果你这样做,你就不能再声称你不知道自己在做危险的事情。

在回答这个问题之前,让我问你,如果它是有效的,你会用这样的指针做什么

假设您有(函数内部)

在这种情况下,如果变量是您想要的
int
,那么没有理由不使用
int
变量

假设您有(函数内部)

在这种对象别名中,可以使用,但允许这样的构造对编译器来说是一件痛苦的事情。编译器可以自由地假设,而且有些编译器确实假设,
*p
的修改对
a
的值没有影响,因此仍然返回未修改的3.14

如果您正在查找后一种情况,则可以使用
union
,这既可以让其他读者更清楚地看到您的代码,也可以让编译器更清楚地看到您的代码:

union {
  float f;
  int i;
} u;
u.f = 3.14;
++u.i;
return u.f;

所以,回答:这是为了防止你射中自己的脚。这是不允许的,因为这样的指针不可能有用。它可能有用的一种情况实际上是它不起作用的情况,还有另一种语言构造可以处理它,并正确地处理它。

还有一个简单的问题,就是取消对指针的引用

something=*指针


取消引用指针时应读取多少数据?编译器必须知道数据类型,才能对数据执行诸如fetch、add等操作。

让我们通过一个示例来理解它

int main()
{
    char i = 8;
    int *ptr = &i;
    printf("Value of i = %d", *ptr);
    return 0;
}
答:它将打印一些垃圾,因为它在内存中取消引用了4个字节。 因此,如果您使用char
*ptr=&i,它将取消引用1个字节,依此类推。。

它将给出正确答案。

由于指针运算的原因:
ptr+1
还应指向
int
(如果初始
ptr
指向更大的聚合对象内部)。
union {
  float f;
  int i;
} u;
u.f = 3.14;
++u.i;
return u.f;
int main()
{
    char i = 8;
    int *ptr = &i;
    printf("Value of i = %d", *ptr);
    return 0;
}