Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.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_Memory Management - Fatal编程技术网

C语言中的地址加法和乘法

C语言中的地址加法和乘法,c,memory-management,C,Memory Management,在C语言中,有没有一种方法可以将两个内存地址相加或将一个内存地址与一个数字相乘 如果是,怎么做?例如,假设我有地址: void * p = (void *) 0x80000000; 我想乘以2或者加上另一个地址,来改变变量的当前地址 值0x28ff44不是“变量地址”p,它只是变量的值。因为变量是指针,所以值是地址。您当然可以通过转换为整数/从整数来修改该值,就像它是一个整数一样,但您为什么要这样做呢 下面是一个将指针值加倍的愚蠢函数: void * double_address(void *

在C语言中,有没有一种方法可以将两个内存地址相加或将一个内存地址与一个数字相乘

如果是,怎么做?例如,假设我有地址:

void * p = (void *) 0x80000000;

我想乘以2或者加上另一个地址,来改变变量的当前地址

0x28ff44
不是“变量地址”
p
,它只是变量的值。因为变量是指针,所以值是地址。您当然可以通过转换为整数/从整数来修改该值,就像它是一个整数一样,但您为什么要这样做呢

下面是一个将指针值加倍的愚蠢函数:

void * double_address(void *p)
{
   const intptr_t pi = (intptr_t) p;

   return (void *) 2 * pi;
}
在C语言中,不能有意义地*将两个地址相加,或将一个地址乘以一个数字或另一个地址。允许的两个操作是减去指向连续内存块的地址,以及向地址添加正整数或负整数。将两个地址相乘或相加没有意义,因为结果不会产生有意义的地址



*这样想:因为地址只是数字,而且数学允许你自由地乘法和加法,并不意味着数学运算的结果会产生任何有意义的结果。例如,您当然可以将机场跑道的长度(以英寸为单位)与飞机油箱的容量(以加仑为单位)相加。通过这种奇怪的计算,您可能会得到一个数字,但它仍然只是一个数字序列,在物理世界中没有任何意义。

我知道您唯一能做的就是向指针添加一个整数值,这将导致指针在内存中移动
sizeof(pointertype)

例如:

int* ptr;
int arr[2];
//put some values in arr;
ptr = &arr[0];
ptr = ptr + 1; // will cause the pointer to move along in the array by `sizeof(int)`

以我从未听说过或见过的任何其他方式添加或增加地址。

你能解释一下你想做什么吗

可以将变量复制到另一个指针,然后设置为设置第一个变量

// Creates new pointer with new address (why ?)
void* new_var_ptr = malloc( <size_of_p> );

// Copy content of "p" address to "new_var_ptr" address
memcpy( new_var_ptr, p, <size_of_p> );

// Set "p" content to NULL (optional)
memset( p, 0, <size_of_p> );

// Set "p" to NULL (optional)
p = NULL
//使用新地址创建新指针(为什么?)
void*new_var_ptr=malloc();
//将“p”地址的内容复制到“new_var_ptr”地址
memcpy(new_var_ptr,p,);
//将“p”内容设置为空(可选)
memset(p,0,);
//将“p”设置为空(可选)
p=NULL

然后,“new_var_ptr”将指向p的前面内容。

在C中添加两个地址是无效的,并且很可能永远不会执行任何您想要执行的操作。您可能需要添加从一个指针到另一个指针的偏移量,例如:

 char *ptr1 = ...;
 char *ptr2 = ...;   
 ptrdiff_t d = ptr1 - ptr2;
 char *ptr3 = ptr2 + d; 
[请注意,只有当
ptr1
ptr2
指向“同一对象”(即相同的分配或相同的数组或类似对象)时,上述内容才正式有效]


将一个指针与另一个指针相乘将更加毫无意义[请原谅双关语]。由于指针往往是相当大的数字,两个指针相乘的乘积也可能溢出结果,使其更加无用

类型转换可以工作,但它的意义不大,而且
sizeof(int)
可能不会=
sizeof(void*)
在某些平台上
(void*)0x8000000
很可能不是地址。您在对其中一个答案的注释中描述的问题,管理内存并将内存区域划分为多个部分,不需要添加地址或将地址乘以数字。它只需要在地址中添加整数(或从中减去整数),并对整数(而不是地址)进行普通算术运算。谢谢大家!我确实用unwind的例子解决了这个问题,正如你提到Eric时,将intptr改为uint32;)0x80000000怎么样?不进行转换是不可能的?@feruz不,不进行转换,您只能在狭窄的范围内向指针添加整数(或从指针中减去整数或指针)。但是,由于目前还没有已知的将指针相乘或将指针添加到指针的合理用途,所以到目前为止,它还没有被遗漏。地址是指向对象的指针值,但并非所有指针值都是地址<代码>无效*foo=0foo的值不是地址,因为它不指向对象。@请解开,谢谢您的示例,我已将intptr\t更改为uint32\t,并设法使其工作!感谢大家的及时回复!干杯,我正在尝试管理内存,选择/滑动到某些部分!我有地址和长度的开头。我想我可以从头开始,然后等分,再加上下一块。。我希望你有这个想法?!这样想未必有帮助。“Symbolics Lisp机器是一种带标记的体系结构,它甚至没有传统的数字指针;它使用这对指针(基本上是一个不存在的句柄)作为C空指针。”——@ModifiableValue
的句柄最终在内部表示为一些无意义的数字。一旦你得到这个数字,你就可以把它乘以任何适合你计算器屏幕上的数字,然后从中得到一系列的数字。不用说,新的数字序列将和原来的序列一样毫无意义。