33
#include<stdio.h>
int main(void){
  int *ptr,a,b;
  a = ptr;
  b = ptr + 1;
  printf("the vale of a,b is %x and %x respectively",a,b);

  int c,d;
  c = 0xff;
  d = c + 1;
  printf("the value of c d are %x and %x respectively",c,d);
  return 0;
}

出力値は

the vale of a,b is 57550c90 and 57550c94 respectively
the value of c d are ff and 100 respectively%  

実際には ptr + 1 であることが判明しましたが、なぜこのように動作するのでしょうか?

4

6 に答える 6

47

ポインターは配列と互換性があるように設計されているため、次のようになります。

*(pointer + offset)

と同等です

pointer[offset]

したがって、ポインター演算はバイト単位では機能しませんが、sizeof(pointer base type)-bytes サイズのブロック単位で機能します。

于 2012-07-22T07:06:16.430 に答える
36

ポインタとは何かを考えてみてください...それはメモリアドレスです。メモリ内のすべてのバイトにはアドレスがあります。したがって、int4 バイトの があり、そのアドレスが 1000 の場合、1001 は実際にはその 2 番目のバイトでありint、1002 は 3 番目のバイトであり、1003 は 4 番目のバイトです。のサイズはintコンパイラごとに異なる可能性があるため、ポインタをインクリメントするときに の中間点のアドレスを取得しないことが不可欠ですint。そのため、データ型に基づいてスキップするバイト数を計算する作業は自動的に処理され、取得した値を気にせずにそのまま使用できます。

Basile Starynkvitch が指摘しているように、この量はsizeof、指定されたデータ メンバーのプロパティによって異なります。アドレスがシーケンシャルであっても、オブジェクトのポインタは、それらのオブジェクトを格納するために必要な実際のメモリ スペースを考慮する必要があることを忘れがちです。

于 2012-07-22T07:10:32.730 に答える
8

ポインター演算は難しいテーマです。ポインターの追加とは、次のポイントされた要素に渡すことを意味します。したがって、アドレスは指定されたsizeof 要素によってインクリメントされます。

于 2012-07-22T07:08:20.683 に答える
2

ポインターは、オブジェクトが割り当てられたメモリの特定のバイトを指すために使用されます (技術的にはどこでも指すことができますが、そのように使用されます)。ポインター演算を行う場合、指しているオブジェクトのサイズに基づいて動作します。あなたの場合、それはそれぞれ4バイトのサイズを持つ整数へのポインタです。

于 2012-07-22T07:07:07.163 に答える
1

ポインタを考えてみましょうp。式p+n(unsigned char *)p + n * sizeof *p(because sizeof(unsigned char) == 1) のようなものです。これを試して :

#include <stdio.h>
#define N   3

int
main(void)
{
    int i;
    int *p = &i;
    printf("%p\n", (void *)p);
    printf("%p\n", (void *)(p + N));
    printf("%p\n", (void *)((unsigned char *)p + N * sizeof *p));
    return 0;
}
于 2012-07-22T12:23:08.047 に答える