配列アドレスをとる識別子(&s+1,s+1,&s[0]+1)について

4427 ワード

 1 #include <stdio.h>

 2 #include <malloc.h>

 3 

 4 int main()

 5 {

 6 char s1[] = {'H', 'e', '1', '2', 'o'};

 7 char *p=(char *)(s1+3);

 8 printf("*p:%c
",p[0]); 9 char *p2=(char *)(&s1[0]+4); 10 printf("*p2:%c
",p2[0]); 11 char *p3=(char *)(&s1+1); 12 printf("*p3:%c
",p3[-1]); 13 14 return 0; 15 }

出力:*p:2*p 2:o*p 3:o
これまで、配列値をとるときにs 1+2,&s 1[0]+2,&s 1+2の区別ができなかったが、今日はわざわざテストした.
s1+2:
s 1配列0ビットから2ビット下に移動する値を指します.
&s1[0]+2:
s 1+2と同様に、s 1配列0ビットから2ビット下に移動する値を指す.
特に注意点:&s 1+1:
s 1配列全体の次の位置に移動し、s 1配列を移動したことに相当する.
特に注意:
int main(){ char *lines[5] = { "COSC1283/1284", "Programming", "Techniques", "is", "great fun"}; char *str1 = lines[1]; char *str2 = *(lines + 3); char c1 = *(*(lines + 4) + 6); char c2 = (*lines + 5)[5]; char c3 = *lines[0] + 2; printf("str1 = %s", str1); printf("str2 = %s", str2); printf("c1 = %c", c1); printf("c2 = %c", c2); printf("c3 = %c", c3); return EXIT_SUCCESS;}
出力:
str1 = Programming

str2 = is

  c1 = f

  c2 = 2

  c3 = E

  • lines[1]:文字列string 1、すなわちstring 1のヘッダアドレスを指すポインタです.
  • *(lines+3):lines+3はlines[5]配列の3番目の要素のアドレス、*(lines+3)は3番目の要素であり、文字列string 3を指すポインタである.
  • *(*(lines+4)+6):*(lines+4)+6==lines[4]+6==string 4+6は、文字列string 4の6番目の文字のアドレス、すなわちfのアドレスであり、*(*(lines+4)+6)は文字fを表す.
  • (*lines+5)[5]:*lines+5は文字列string 0の5番目の文字のアドレス、すなわち2のアドレスであり、(*lines+5)[5]は*(*(*lines+5+5)に等価であり、10番目の文字、すなわち2を表す.
  • *lines[0]+2:*lines[0]は、文字列string 0の0番目の文字のアドレス、すなわちCのアドレスである.文字は整数演算で、まずその文字に対応するASCIIコード値に変換されてから演算されるので、*lines[0]+2=67+2=69です.ただし、出力文字が要求されるため、69に対応する文字、すなわちEに変換される.

  •  
    一方、linesはポインタを指すポインタであり、char**のタイプであるため、*linesは文字を指すポインタであり、*linesは具体的な文字である.この点はとても重要で、必ず理解しなければなりません.