在C指针,为什么这个输出?

时间:2017-11-10 08:59:16

标签: c pointers

嘿,我是用C编程的新手,我正在尝试理解指针和地址并运行此代码我得到了输出: v = 3003 '内存地址' * p = 3003

我理解最后两个,但有人可以帮助解释为什么v = 3003?我最初的理解是它会产生3002,所以我理解寻址和指针线'p =& v'在这方面起作用,但我不明白如何。非常感谢任何解释,谢谢!

#include <stdio.h>
int main() {
    int v = 0x3002;
    int* p = 0x3000;
    p = &v;
    (*p)++;
    printf("v = %x\n", v);
    printf("%x\n", p);
    printf("*p = %x\n", *p);
}

5 个答案:

答案 0 :(得分:5)

您的代码行为未定义。您不能为与您不拥有的内存对应的指针分配地址,但NULL除外,一个超出数组末尾,或者超过标量结尾。 (出于某种原因,这是一个鲜为人知的规则。)

所以你的第一份工作就是删除int* p = 0x3000;。替换为int* p;。然后未定义的行为就消失了。

您的代码

p = &v;
(*p)++;

p设置为v的地址,并通过指针递增v

答案 1 :(得分:1)

p = &v;

p现在包含v的地址。

(*p)++;

增加p中包含的地址的值。该值为0x3002;

因此它变为0x3003

现在通过v更改p

这就是输出的原因。

您可以通过强制转换指定指针。

int *p=(int*)0x3000;

代码将是: -

#include <stdio.h>
int main() {
    int v = 0x3002;
    int* p;
    p=&v; 
    (*p)++;
    printf("v = %x\n", v);
    printf("%x\n", p);
    printf("*p = %x\n", *p);
}

同样分配指针变量是未定义的行为

来自标准§6.3.2.3

  

整数可以转换为任何指针类型。除了   以前指定的,结果是实现定义的,可能   没有正确对齐,可能不会指向一个实体   引用类型,可能是陷阱表示。)

答案 2 :(得分:1)

p=&v语句将变量v的地址分配给p。换句话说,从那时起,p指向v存储其值的内存地址。然后(*p)++递增它:p是内存中的指针,*p取消引用此地址,以便增量操作++不适用于p(在哪个案例p将指向下一个内存地址),但指向p给出的地址处的值。

答案 3 :(得分:0)

首先,在进入指针的细节之前,C语言提供的内存访问以这种方式使用是很危险的。通常你没有像你在代码中提到的那样定义要保存变量的位置的地址或指针本身的地址。

#include <stdio.h>
int main() {
    int v = **0x3002**;
    int* p = **0x3000;**
    p = &v;
    (*p)++;
    printf("v = %x\n", v);
    printf("%x\n", p);
    printf("*p = %x\n", *p);
}

但是,由于使用p =&amp; v,p分配给p的值被忽略,p具有由编译器或OS分配给v的正确地址。当你定义int v;在运行时分配一个内存位置,然后p将获得该地址。

通常,您尝试创建一个整型变量和一个指向此变量的指针,以便对同一个变量进行两次引用。

通常,在使用变量或指针时,您不需要跟踪变量或指针的地址值,只需知道如何正确使用它们以及何时使用它们

指针使用的常规检查

#include <stdio.h>
void changeA( int*);
int main() {
   int a=1;
   printf("%d",a);
   changeA(&a);
   printf("%d",a);
   return 0;
}

void changeA(int* pA){
  *pA=2;
}

<强>输出 1 2

前面的示例显示了指针的用法,您可以在其中访问具有不同范围的变量,变量a在main函数的范围内定义,并通过使用指针为函数 changeA 该函数可以访问变量a保存在内存中的内存位置,并直接从另一个函数范围进行更改。

通常在需要为函数提供多个输出时使用的指针, return 可用于仅返回一个变量。使用指针,您将拥有每个功能的无限功能。

答案 4 :(得分:0)

这是已发布代码的正确编写版本,带有适当的注释

#include <stdio.h>

int main( void ) 
{
    int v = 0x3002;   // sets an integer value into 'v'
    int* p = &v;      // get address of 'v' and places that address in 'p'
    (*p)++;           // increments the contents of 'v', 
                      // using 'p' 
                      // while paying attention to operator precedence in C

    // displays on terminal, the contents of 'v' I.E.0x3003
    printf("v = %x\n", v);   

    // displays on terminal, the address of 'v' (contents of 'p')
    printf("%p\n", (void*)p);

    // displays on terminal, the contents of 'v', which is pointed to by 'p'
    printf("*p = %x\n", (unsigned int)*p);
}