请求对数组中指针行为的说明

Request explanation on the behaviour of pointers in array

本文关键字:说明 指针 数组 请求      更新时间:2023-10-16

i m使用Rextester(在线编译器)运行此操作。我遵循了一个教程,但有我不明白的东西。

我认为最好将我的问题直接写在代码中。

//gcc 5.4.0
#include <stdint.h>
#include  <stdio.h>
uint8_t var1 = 17;
uint8_t var2 = 23;
uint8_t arr[] ={7,9,11};
uint64_t *ptr1;//pointer
uint64_t *ptr2;
uint64_t *ptr3;
int main(void)
{
    printf("var1: %dn", var1) ;
    //connecting pointer to address
    ptr1 = &var1;
    printf("address of ptr1: %dn", ptr1) ;
    printf("value of ptr1: %dnn", *ptr1) ;
    //connecting pointer to address + 1
    ptr2 = &var1 +1;
    printf("address of ptr2: %dn", ptr2) ;
    //assign value to pointer
    *ptr2 = var2;
    printf("value of ptr2: %dnn", *ptr2) ;
    //try on array
    ptr3= &arr;//no need to point element 0, or yes? 
    printf("address of ptr3: %dn", ptr3) ;
    printf("value of ptr3: %dnn", *ptr3) ;//i expect 7
    return 0;
}

任何帮助都将非常感谢,以帮助我了解C和CPP中指针的正确行为我做了很多尝试,但我无法将指针链接到数组

MATO响应后编辑:

您认为这是一种使用指针和数组的干净方式吗?还是有更好的解决方案来照顾不覆盖内存?

//gcc 5.4.0
#include <stdint.h>
#include  <stdio.h>
uint16_t var = 17;
uint16_t arr[] ={3,5,7,11,13};
uint16_t *ptr;
int main(void)
{
printf("var: %dn", var) ;
//connecting pointer to address
ptr = &var;
printf("address of ptr: %dn", ptr) ;
printf("value of ptr: %dnn", *ptr) ;
//try on array
for (uint16_t n =0;n<5;n++){
ptr= &arr[n] ;
printf("item: %d value: %d ads: %d pointer: %dn", n, arr[n], ptr, *ptr) ;
}
return 0;
}

看来您确实了解了什么指针,并且可以与基本类型一起使用。

您的代码中有两个问题。首先是该部分:

//connecting pointer to address + 1
ptr2 = &var1 + 1;

在这里,您将某些地址分配给了变量ptr2。到目前为止,这没有什么危险的。

,但随后您将值分配给该地址的内存

//assign value to pointer
*ptr2 = var2;

这很危险,因为您作为开发人员不知道该地址存储的内容。即使您现在很幸运,并且没有用于其他任何内容的部分,也很可能会改变您的程序更长的时间,然后您很难搜索该错误。

现在数组通常有点令人困惑,因为当您创建这样的数组时:

uint8_t arr[] = {7,9,11};

发生了三件事。

  1. 您的程序分配了持续的内存块,该内存符合3个类型uint8_t的变量。在此上下文中的3个变量称为元素。
  2. 元素将获得提供的初始值7、9和11。
  3. 第一个元素的地址(包含值7)将存储在arr中。

因此arr实际上是类型uint8_t *

为了使最后一部分做您的期望,您只需要更改这一行(删除&amp;):

ptr3 = arr;

编辑:顺便说一句观看并了解此课程,您将成为C内存操作的专家。视频有些过时,但是请相信我,那家伙很棒。

edit2:我刚刚意识到另一个答案是绝对正确的,您确实需要匹配类型。

您正在犯很多错误。到目前为止,G 没有编译代码,并解释了为什么很好。

指针是一个地址。没有"连接指针要寻址"。 ptr1 = &var1;的字面意思是" var1的商店地址 ptr1 "

您使用不兼容的指针类型。因此,只要您退出它(例如使用*),您就会涉及不确定的行为。

我很确定您可以将任何类型的数据重新诠释为char*unsigned char*,我对等效类型(例如uint8_t,即单个字节类型)的映像是正确的。

但是,您正在以其他方式进行,您声明了1字节数据,并且假装它是4个字节int。基本上,您强制该程序读取内存范围。

事实,*ptr1*ptr2给出您期望的结果是一个相当幸运的巧合。它们背后的记忆可能被归零。对于ptr3,不是因为您已经填充了数组的其他元素(7和9)。

我相信您还使用错误的类型说明符进行打印。%d用于intuint8_t应描述为hhuuint64_tlu。由于平台特定的宽度和整数促销,我并不是100%确信这是多么致命的。

您应该为指针和变量使用匹配类型。