我是一名专业的 C# 程序员,但我对 C++ 很陌生。我对指针的基本概念很好,但我一直在玩。您可以通过将指针转换为 来获取指针的实际整数值int:
int i = 5;
int* iptr = &i;
int ptrValue = (int)iptr;
Run Code Online (Sandbox Code Playgroud)
这是有道理的;这是一个内存地址。但是我可以移动到下一个指针,并将其转换为int:
int i = 5;
int* iptr = &i;
int ptrValue = (int)iptr;
int* jptr = (int*)((int)iptr + 1);
int j = (int)*iptr;
Run Code Online (Sandbox Code Playgroud)
我得到了一个看似随机的数字(虽然这不是一个好的 PSRG)。这个数字是多少?它是同一进程使用的另一个号码吗?它可能来自不同的过程吗?这是不好的做法,还是不允许的?如果没有,这有什么用吗?这有点酷。
如果你编译、链接和运行这样的东西:
global _start
section .text
_start:
jmp message
proc:
...
message:
call proc
msg db " y0u sp34k 1337 ? "
section .data
Run Code Online (Sandbox Code Playgroud)
我画这个是为了更好地理解。在 PC 的内存中有连续的内存区域,长度为 1 个字节(绿色区域)。它们可以分组以表示更大的数据(如int我们的示例中的an )。
我想添加到这张图片中的是,绿色方块是连续的地址,如0x000000后跟0x000001等。然后地址从arr四跳,0x000000下一个将是0x000004(因为int在这方面是4bytes)。
代码_1:
int arr[4] = {1,2,3,4};
int *p = arr;
cout << p << endl;
cout << ++p << endl;
cout << ++p << endl;
cout << ++p << endl;
Run Code Online (Sandbox Code Playgroud)
输出_1:
0x69fedc
0x69fee0
0x69fee4
0x69fee8
Run Code Online (Sandbox Code Playgroud)
代码_2:
char arrr[5] = {'1','2','3','4', '\n'};
char *ptr = arrr;
cout << &ptr << endl;
cout << &(++ptr) << endl; …Run Code Online (Sandbox Code Playgroud) 例如,当初始化一个指向 int 的指针时,我们使用:
var pointer *int
Run Code Online (Sandbox Code Playgroud)
为什么语法不是:
var pointer &int
Run Code Online (Sandbox Code Playgroud)
对我来说,第二个版本更有意义,因为它读起来像“变量‘指针’是一个整数的内存地址”
或者换句话说,我发现“*”既用于定义内存地址类型(如上所述)又用于取消引用,例如 *pointer = 123
这是否像看起来那样令人困惑,还是我在这里遗漏了什么?
我有以temp成员命名的结构n:
struct temp
{
int n;
}
Run Code Online (Sandbox Code Playgroud)
我希望声明一个指向p访问成员的指针n。
struct temp *p
Run Code Online (Sandbox Code Playgroud)
如何进入构件n由另一个指针p1指向指针p。
在尝试向使用&运算符获得的地址添加偏移量时,我遇到了一个非常奇怪的行为。因此,当我尝试向该地址添加任何数字时,结果是该地址加上我的数字乘以0xE0(224)。
这些是 Visual Studio 中监视列表的屏幕截图。每个截图的第一行是我的对象地址的访问,这是正确的。第二行是相同的访问,但我们向它添加了变量偏移量。第三行只是偏移量本身。
如您所见,第一个屏幕截图上的一切都很好。但是在第二个上,加法是0xE0( 0xE38-0xD58=0x0E0) 而不是 1 应该是。在最后一个屏幕截图中,添加的0x1C0是2*0xE0.
在第二行,我希望0x00000255ef9bed58在第一个屏幕截图、0x00000255ef9bed59第二个屏幕截图和0x00000255ef9bed5a最后一个屏幕截图中看到。
假设我这样初始化数组和变量:
int arr1d[3] = { 1, 2, 3 };
int* arrptr = arr1d;
int (*ptr1d)[3] = &arr1d;
int arr2d[2][3] = { {1, 2, 3}, {4, 5, 6} };
int (*ptr2d)[3] = arr2d;
Run Code Online (Sandbox Code Playgroud)
所以,arr1d是一个由 3 个整数组成的数组。在底层,arr1d是一个指向数组第一个元素的指针,即&arr1d[0]. 因此,我们可以赋值arr1d给int* arrptr。
ptr1d指向一个由 3 个整数组成的数组。arr1d是int*指向&arr1d[0],但为什么是&arr1d类型int (*)[3]?天真地,我认为写作&arr1d只是给了我们一个地址来分配给指针。这是特定于指向数组的指针吗?
显然,arr2d是类型int (*)[3](我从这篇文章中学到的)。双方ptr2d并*ptr2d具有相同的值,所以这是为什么第二解引用甚至是必要的?我的想法是,这可能是因为ptr2d类型是int (*)[3] …
c++ pointers multidimensional-array memory-address dereference
我在玩指针,我注意到一件奇怪的事情。
我有一个结构如下:
typedef struct list_element_struct {
uint32_t x;
uint32_t y;
uint32_t z;
struct list_element_struct *next;
}list_element;
Run Code Online (Sandbox Code Playgroud)
据我所知,unsigned int 的大小为 4 个字节,指针的大小为 8 个字节。这里也有 8 个字节对齐,所以这个结构的大小是 24 个字节。
我已经初始化了上述结构对象的列表,list_element els[5];并将其中的每条数据设置为 0memset(els,0,5*sizeof(list_element));
现在我正在尝试使用以下代码查看它们的内存位置:
printf("%p start location of els\n", &(els));
printf("%p start location of els->x\n", &(els->x));
printf("%p start location of els->y\n", &(els->y));
printf("%p start location of els->z\n", &(els->z));
printf("%p start location of els->next(pointer)\n", &(els->next));
printf("%p start location of els+1\n", &(els[1]));
Run Code Online (Sandbox Code Playgroud)
我打印出来的是:
0x7ffeeba4a970 start location of els
0x7ffeeba4a970 start location of …Run Code Online (Sandbox Code Playgroud) 你能帮我理解这个基本项目吗:
我有两个变量 i 和 J ,我的查询是我已经初始化了“I”,然后是“J”,但是第一个地址被分配给了 J 而不是“I”。
你能帮我理解为什么吗?
I 和比 J 高 4 位的地址
#include<stdio.h>
int main()
{
int i;
printf("%d",sizeof(int));
printf("enter the number to multiply wuth 1 through 10:");
scanf("%d",&i);
printf("size of I:%d\n",sizeof(i));
for(int j=0;j<=10;j++){
printf("%d\n",i*j);
printf("Address of j:%d\n",&j);
}
printf("%d",&i);
return 0;
}
Run Code Online (Sandbox Code Playgroud) 考虑汇编代码 -mov edi, offset newarray
根据我所阅读的内容,这会将 的地址newarray放入寄存器edi
我不明白的是这个术语 这个术语offset的英文含义如何
适合这里。
memory-address ×10
c++ ×5
pointers ×4
c ×3
assembly ×2
dereference ×2
struct ×2
x86 ×2
arrays ×1
compilation ×1
go ×1
hex ×1
int ×1
masm ×1
member ×1
memory ×1
offset ×1
reference ×1
terminology ×1