同一个C指针显示不同的值?

同一个C指针显示不同的值?,c,gcc,c99,C,Gcc,C99,我正在运行这个程序: #include<stdio.h> void main(){ int num = 1025; int *poinTer = &num; char *pointChar = poinTer+1; *pointChar = 'A'; printf("Size of Integer: %d\n", sizeof(int)); printf("Address: %d, Value: %d\n", poinTer, *poinTer);

我正在运行这个程序:

#include<stdio.h>

void main(){
  int num = 1025;
  int *poinTer = &num;
  char *pointChar = poinTer+1;
  *pointChar = 'A';

  printf("Size of Integer: %d\n", sizeof(int));
  printf("Address: %d, Value: %d\n", poinTer, *poinTer);
  printf("Address: %d, Value: %c\n", poinTer+1, *(poinTer+1));
  printf("Address: %d, Value: %c\n", pointChar, *pointChar);
}

这里发生了什么?

当您对指针执行
+1
时,它不一定会将内存地址增加1。它将其增加
sizeof(*ptr)

在这种情况下,
指针+1
相当于
(char*)指针+sizeof(int)
。这实际上使处理数组变得更加容易

老式的
ptr[i]
*(ptr+i)
的语法糖。因此,如果您有一个由10个整数组成的数组,
ptr[4]
将指向第5个元素,而不是距离基址4个字节(因为整数通常是4或8个字节)

所以你实际上做的是:

  • 在堆栈上创建一个
    int
    num
    ),并给它赋值
    1025
  • 在堆栈上创建了一个
    int*
    指针
    ),并为其分配了
    num
  • 将指针递增
    sizeof(int)
    (无意中指向不同的内存地址),然后将其强制转换为
    char*
    ,并将其分配给新指针
  • 将指向此新内存地址的字节赋值为
    65
    'A'
  • 这可能是您想要做的:

    #include<stdio.h>
    
    void main(){
      int num = 1025;
      int *poinTer = &num;
      char *pointChar = (char*)poinTer + 1;
      *pointChar = 'A';
    
      printf("Size of Integer: %d\n", sizeof(int));
      printf("Address: %d, Value: %d\n", poinTer, *poinTer);
      printf("Address: %d, Value: %c\n", (char*)poinTer + 1, *((char*)poinTer+1));
      printf("Address: %d, Value: %c\n", pointChar, *pointChar);
    }
    
    #包括
    void main(){
    int num=1025;
    int*指针=&num;
    char*pointChar=(char*)指针+1;
    *pointChar='A';
    printf(“整数的大小:%d\n”,sizeof(int));
    printf(“地址:%d,值:%d\n”,指针,*指针);
    printf(“地址:%d,值:%c\n”,(char*)指针+1,*((char*)指针+1));
    printf(“地址:%d,值:%c\n”,pointChar,*pointChar);
    }
    
    这里是未定义的行为。:)表达式指针+1指向对象编号之外的对象。您的意思似乎是char*pointChar=(char*)指针+1,因此您不能将转换说明符%d用于指针。未定义的行为是未定义的。幸运的是,您没有遇到访问冲突,因为您从未为指针+1(num+4字节)分配空间。您可能是在将“A”分配到堆栈上自己的位置时丢弃了pointChar。指针值1704004673是十六进制65910C41。最后的41是你的“A”字符。分配
    *pointChar='A'
    时所做的是修改指针的efl;换句话说,
    char*pointChar=poinTer+1
    makepointchar指向自身,因为它正好位于堆栈上的指针之后。感谢您清楚地写下这篇文章。实际上,我对指针是如何存储在内存中感到困惑。我认为它们只是存储为整数,这似乎不正确。“它们似乎也包含类型。”AnttiHaapala明白了。我现在明白了很多细节。我还有一个小小的疑问。char*pointChar=(char*)指针+4;将导致未定义的内存区域,对吗?因为,我们最初为integer保留了4个字节,所以我们可以将事情更改为+3,但之后编译器会给我们任何随机内存,对吗?@KshitijKumar有点像是,假设
    sizeof(int)
    是4。
    +4
    是特殊的,因为它指向“刚过终点”,计算是合法的,但您无法检索它指向的值。但是如果指针超出范围。i、 e.即使刚过终点(例如+5),算术本身的行为也没有定义。非常感谢您的澄清。我想大部分的部分现在都清楚了。
    #include<stdio.h>
    
    void main(){
      int num = 1025;
      int *poinTer = &num;
      char *pointChar = (char*)poinTer + 1;
      *pointChar = 'A';
    
      printf("Size of Integer: %d\n", sizeof(int));
      printf("Address: %d, Value: %d\n", poinTer, *poinTer);
      printf("Address: %d, Value: %c\n", (char*)poinTer + 1, *((char*)poinTer+1));
      printf("Address: %d, Value: %c\n", pointChar, *pointChar);
    }