请求解释数组中指针的行为

时间:2017-10-02 22:36:03

标签: c++

我使用rextester(在线编译器)运行它。我遵循了一个教程,但有些事情我不明白。

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

    $(function() {
        var job = $.connection.myHub;

        job.client.displayStatus = function () {
            getData();
        };

        $.connection.hub.start();
        getData();
    });

    function getData() {
        var params = (new URL(document.location)).searchParams;
        var id = params.get("id");
        var dt = $("#accessdate").val();

        $.ajax({
            url: 'dupdatesservice.asmx/GetData',
            data: JSON.stringify({dnum: id, date: dt}),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            type: "POST",
            success: function (data) {
                if (data.d.length > 0) {
                    $("#testdiv").prepend(data.d[0].comment);
                }
            }
        });
    }

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

mato回复后编辑:

您认为这是一种使用指针和数组的简洁方法吗?或者有更好的解决方案,照顾不覆盖内存?

//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: %d\n", var1) ;

    //connecting pointer to address
    ptr1 = &var1;
    printf("address of ptr1: %d\n", ptr1) ;
    printf("value of ptr1: %d\n\n", *ptr1) ;

    //connecting pointer to address + 1
    ptr2 = &var1 +1;
    printf("address of ptr2: %d\n", ptr2) ;

    //assign value to pointer
    *ptr2 = var2;
    printf("value of ptr2: %d\n\n", *ptr2) ;

    //try on array
    ptr3= &arr;//no need to point element 0, or yes? 
    printf("address of ptr3: %d\n", ptr3) ;
    printf("value of ptr3: %d\n\n", *ptr3) ;//i expect 7
    return 0;
}

2 个答案:

答案 0 :(得分:2)

你犯了很多错误。到目前为止,g ++没有编译代码并解释了为什么不错。

指针是一个地址。没有&#34;连接指针到地址&#34;。 ptr1 = &var1;在名为var1 &#34;

的变量中按字面意思&#34; 存储地址ptr1

您使用不兼容的指针类型。因此,只要您取消引用它(例如使用*),您就会进入未定义的行为。

我非常确定您可以将任何类型的数据重新解释为char*unsigned char*,我认为对于像uint8_t这样的等效类型,即单字节类型,这是正确的。

然而,您正在采用另一种方式,声明1字节数据,并假装它是4字节int。基本上你强制程序从变量边界读取内存。

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

我相信你也会使用错误的类型说明符进行打印。 %d适用于intuint8_t应定义为hhuuint64_t定义为lu。我并不是100%确信这是多么致命,因为平台特定的宽度和整数促销。

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

答案 1 :(得分:2)

您似乎明白了什么是指针,您可以将它们与基本类型一起使用。

您的代码中存在两个问题。首先是这部分:

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

您在此处为变量ptr2分配了一些地址。到目前为止,没有什么危险的。

但是你在那个地址为内存分配一个值

//assign value to pointer
*ptr2 = var2;

这很危险,因为作为开发人员,您不知道该地址存储的是什么。即使你现在很幸运,并且那部分内存没有被用于其他任何东西,一旦你的程序变得更长,它很可能会改变,然后你将很难找到错误。

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

uint8_t arr[] = {7,9,11};
发生了三件事。

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

    为了让最后一部分符合您的预期,您只需要更改这一行(删除&amp;):

    ptr3 = arr;
    

    编辑:BTW观察并了解this course,您将成为C内存操作方面的专家。视频有点陈旧,但相信我,这家伙很棒。

    EDIT2:我刚刚意识到其他answer绝对正确,你真的需要匹配这些类型。