因此,正如我从Michael Burr 对此答案的评论中所学到的,C标准不支持从数组中第一个元素之后的指针进行整数减法(我想这包括任何已分配的内存).
从C99 + TC1 + TC2组合的 6.5.6节(pdf):
如果指针操作数和结果都指向同一个数组对象的元素,或者指向数组对象的最后一个元素,则评估不应产生溢出; 否则,行为未定.
我喜欢指针算法,但这从来都不是我以前所担心的.我一直认为给定:
int a[1];
int * b = a - 3;
int * c = b + 3;
Run Code Online (Sandbox Code Playgroud)
那个c == a.
因此,虽然我相信我以前做过那样的事情而且没有被咬过,但这一定是由于我曾经使用的各种编译器的善意 - 他们已经超出了标准要求的范围.使指针算术以我认为的方式工作.
所以我的问题是,这有多常见?是否有常用的编译器不能为我做那种善意?超出数组边界的正确指针算法是一个事实上的标准吗?
public static IntPtr Add(
IntPtr pointer,
int offset
)
Run Code Online (Sandbox Code Playgroud)
这是伟大的,因为它应该解决所有这些问题IntPtr的数学,我们有(1,2,可能更多).
但是为什么offset int呢?
一定不是IntPtr吗?我可以很容易地想象将64位指针偏移超出int范围的值.
例如,考虑Marshal.OffsetOf:
public static IntPtr OffsetOf(
Type t,
string fieldName
)
Run Code Online (Sandbox Code Playgroud)
它返回一个IntPtr作为结构成员的偏移量.这很有道理!并且您无法使用新Add方法轻松使用此偏移量.你必须把它投射到Int64,然后Add循环调用几次.
此外,它似乎杀死了IntPtr.Size与正确编写的应用程序无关的想法.您必须将偏移量转换为特定类型,例如Int64,此时您必须开始管理大小差异.并且想象出128位IntPtr出现时会发生什么.
我的问题是,为什么?
我的结论是否正确,还是我忽略了这一点?
如何使用指针算法打印结构的特定成员?我有一个有2名成员的结构.我想j通过操纵指向该结构的指针的内存来打印出成员.
#include <stdio.h>
#include <conio.h>
typedef struct ASD
{
int i;
int j;
}asd;
void main (void)
{
asd test;
asd * ptr;
test.i = 100;
test.j = 200;
ptr = &test;
printf("%d",*(ptr +1));
_getch();
}
Run Code Online (Sandbox Code Playgroud) 关于数组和指向数组的指针,我有一个相当简单的问题.考虑这段代码片段..
int (*ptr)[3]; //A pointer to an array of 3 ints
int arr1[3] = {2,4,6,};
ptr = &arr1; //ptr now points to arr1
//3 different ways to express the same address
cout << &arr1 << "\t" << arr1 << "\t" << &arr1[0] << endl;
Run Code Online (Sandbox Code Playgroud)
现在如果:
&arr1 == arr1 == &arr1[0]..
Run Code Online (Sandbox Code Playgroud)
为什么这段代码不正确:
ptr = arr1;
Run Code Online (Sandbox Code Playgroud)
要么
ptr = &arr1[0];
Run Code Online (Sandbox Code Playgroud)
这一直让我发疯...所以请任何解释将不胜感激.另外请不要这不是一个家庭作业问题,只是我想要抓住的东西.
int main()
{
int a;
void *p;
p = &a;
printf("%ld\n",(long)p);
p = p+1;
printf("%ld\n",(long)p);
}
Run Code Online (Sandbox Code Playgroud)
在这个程序中,p+1只是将p的值递增1.我知道void pointer arithmetic是不可能的C,所以GCC隐式地这样做.如果是的话,那就是它char pointer.另外,dereferencing如果void指针隐式执行指针运算,为什么不可能使用void指针.
我正在写一个应用程序,我不得不做一些指针算术.但是这个应用程序将在不同的架构上运行!我不确定这是否会有问题,但在阅读本文之后,我认为我必须改变它.
这是我原来的代码,我不太喜欢:
class Frame{
/* ... */
protected:
const u_char* const m_pLayerHeader; // Where header of this layer starts
int m_iHeaderLength; // Length of the header of this layer
int m_iFrameLength; // Header + payloads length
};
/**
* Get the pointer to the payload of the current layer
* @return A pointer to the payload of the current layer
*/
const u_char* Frame::getPayload() const
{
// FIXME : Pointer arithmetic, portability!
return m_pLayerHeader + m_iHeaderLength;
}
Run Code Online (Sandbox Code Playgroud)
很糟糕不是吗!向指针添加 …
我有以下程序,它定义了2个整数和一个指向整数的指针.
#include <stdio.h>
int main() {
int bla=999;
int a=42;
int* pa=&a;
printf("%d \n", *pa);
printf("%d \n", pa);
pa++;
//*pa=666; //runs (no error), but the console is showing nothing at all
printf("%d \n", *pa);
printf("%d \n", pa);
pa++;
//*pa=666; //runs and changes the value of *pa to 666;
printf("%d \n", *pa);
printf("%d \n", pa);
}
Run Code Online (Sandbox Code Playgroud)
输出是:
42
2686740
2686744
2686744 //这个值很奇怪,我想
999
2686748
地址对我来说很有意义,但第四个值很奇怪,因为它正是int的地址.有人可以解释一下这种行为吗?
当我评论*pa = 666(第一个外观)时,控制台什么也没显示,所以这里有一些错误,但编译器没有显示错误.也许这是因为我的系统上的int的大小,我有一个64位的Windows-os,所以也许int是64位而不是32?并且因为第二次增量后*pa值是999而不是第一次?
我相信,有很多C程序员可以解释发生了什么:)
指针存储指向值的存储器地址,因此指针包含的存储器地址与值的存储器地址相同.因此,向这两个内存地址添加1应该会产生相同的结果,这是不会发生的.为什么?这是代码
int main()
{
int ages[] = {23, 43, 12, 89, 2};
int *cur_ages = ages;
printf("\n&cur_ages=%p, &cur_ages+1=%p", &cur_ages, &cur_ages+1);
printf("\n&ages=%p, &ages+1=%p", &ages, &ages+1);
printf("\ncur_ages=%p, cur_ages+1=%p", cur_ages, cur_ages+1);
printf("\n*cur_ages=%d, *cur_ages+1=%d", *cur_ages, *(cur_ages+1));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出是
&cur_ages=0x1ffff85f3d0, &cur_ages+1=0x1ffff85f3d8
&ages=0x1ffff85f3dc, &ages+1=0x1ffff85f3f0
cur_ages=0x1ffff85f3dc, cur_ages+1=0x1ffff85f3e0
*cur_ages=23, *cur_ages+1=43
Run Code Online (Sandbox Code Playgroud)
&age + 1不等于cur_ages + 1.为什么?
我无法理解为什么在这个程序2 - 4给出-1,它已经为指针而不是地址分配了int值,我知道但是当我编译它时编译器给出了一些警告,但编译了程序并执行但是...
程序
#include<stdio.h>
int main(void) {
int *p, *q;
int arr[] = {1,2,3,4};
// I know p and q are pointers and address should be assigned to them
// but look at output, why it evaluates (p-q) to -1 while p as 2 and q as 4
p = arr[1];
q = arr[3];
printf("P-Q: %d, P: %d, Q: %d", (p - q), p, q);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
它给
P-Q: -1, P: 2, Q: 4
Run Code Online (Sandbox Code Playgroud) int main(){
int array[] = [10,20,30,40,50] ;
printf("%d\n",-2[array -2]);
return 0 ;
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以解释-2 [array-2]是如何工作的,为什么[]在这里使用?这是我的任务中的一个问题,它给输出"-10",但我不明白为什么?