• ベストアンサー

c言語の配列の先頭アドレスが偶数アドレスとなる理由について

c言語の配列の先頭アドレスが偶数アドレスとなる理由について 下記のように実行結果をで見ると、配列Sの先頭アドレスと配列Cの先頭アドレス共に偶数アドレスなる理由を教えて頂きたい。 /*list0105*/ #include <stdio.h> main() { char na=1; char nb=1; char c[2] ={1,2}; char s[3] = {1,2,3}; char nc=1; char nd=1; printf("%p\n",&na); printf("%p\n",&nb); printf("%p %p \n", &c[0],&c[1] ); printf("%p %p %p \n", &s[0],&s[1] ,&s[2] ); printf("%p\n",&nc); printf("%p\n",&nd); } 実行結果 0xbffff8cf 0xbffff8ce 0xbffff8cc 0xbffff8cd ← c配列 0xbffff8b0 0xbffff8b1 0xbffff8b2 ← S配列 0xbffff8af 0xbffff8ae

質問者が選んだベストアンサー

  • ベストアンサー
  • zwi
  • ベストアンサー率56% (730/1282)
回答No.2

メモリの配置はコンパイラとコンパイルオプションに依存します。 デフォルトだと、32ビットのメモリ処理単位=4バイトとか8バイトが多いかと。 理由は32ビットCPUが4バイト単位でメモリにアクセスするのでアクセス効率を優先したためです。 例えば、 0xbffff8cc 0xbffff8cd ← c配列 0xbffff8ce 0xbffff8cf 0xbffff8d0 ← S配列 だとしたら、S配列の内容全てを参照するためにCPUは0xbffff8ccと0xbffff8d0の合計8バイトにアクセスする必要が出てきます。無駄ですよね。

dreamsturb
質問者

お礼

回答ありがとうこざいます。S配列 は、CPUのメモリ処理単位4バイトなので、4の倍数のアドレス(0xbffff8b0 )にすれば、アクセスは4バイトで、アクセスは、効率的であると把握しました。今後ともよろしくお願いします。 

その他の回答 (1)

回答No.1

関連するQ&A

  • c言語の境界調整について

    c言語の境界調整について 下記の質問プログラムのp=(int *)s; の境界調整は、intは、偶数の倍数で、charは、1バイトなので 先頭アドレスは、int, charも同じであるので配列全部0となるのでしょうか、    よろしくお願します。 *質問プログラム char s[4] = {1,2,3,4} ; int *p ; main() p=(int *)s;; *p=0 ; printf("%d %d %d %d\n",s[0],s[1],s[2],s[3];

  • C言語について

    「条件演算子(a?b:c)を使って、三つの整数値を読み込んで、その最小値を求めて表示するプログラムを作成せよ」という問題を初心者なりに自分で以下のように解いてみたのですが、もっと簡単に表示できるプログラムがあれば教えてください。 #include<stdio.h> int main(void) { int na,nb,nc,min; printf("整数1:"); scanf("%d",&na); printf("整数2:"); scanf("%d",&nb); printf("整数3:"); scanf("%d",&nc); (na<nb)?min=na:min=nb; printf("最小値は%dです。\n",(nc<min)?min=nc:min); return 0; }

  • C言語のint型の配列が分かりません

    #include<stdio.h> int main(void) { int str[ ]={0,1,2} printf("%s\n", str); return 0; } というプログラムをC言語でつくってみましたが動きません.(012と表示されて欲しかったのですが) int str[ ]={1,2,3}の部分をchar str[ ]={'0','1','2'}とすれば動きます. そこで質問なのですが, printf("~%s~", (配列名));  はchar型の配列にしか適応できないのですか? ※追記 puts関数の定義は int puts (const char *str); であるそうなので char型の仮引数にはchar型のアドレスを渡さなければいけません. ではprintf関数の定義は一体どんなものなのですか?

  • c言語超初心者です。2

    #include <stdio.h> int main(void) { int na,nb, nc; int sum; double ave; puts("三つの整数を入力してください."); printf("整数A:"); scanf("%d", &na); printf("整数B:"); scanf("%d", &nb); printf("整数C:"); scanf("%d", &nc); sum=na+nb+nc; ave=(double)sum/3; printf("それらの合計は%5dです。\n", sum); printf("それらの平均は%5.1fです。\n",ave); return(0); } とういうのを作ったんですが、最後のそれらの合計は%5dとやりその5の意味は整数を10進法で少なくても5桁で表示とありますが、例えば1,2,3と入力しても合計は6とでて5桁ででないんですけど。そういう意味ではありませんか?あとave=(double)sum/3;のところをave=sum/3.0としても問題なくできるのですが、どっちでやったほうがいいとかはありますか?もしあったらその理由も教えてください。

  • C言語のポインタと配列について

    下のコードについて2つ質問があります。 (1) char *p; p = str; ならわかるのですが、なぜ型が違う char *p = str; のような代入がOKなのでしょうか。文字列をコピーするときの   *p = *str; と比較して、とても違和感があります。  str は引数で受けた文字列の先頭アドレス。 (2)   char *str;   str = " 1 23 4 5"; と   char str[] = " 1 23 4 5"; との違いがよくわかりません。 #include <stdio.h> #include <ctype.h> void TrimSpace(char *str) {   char *p = str;        // (1)型が違うのになぜこんな代入をするのか?      while (*str != '\0') {     if ( !isspace(*str) ) {       *p = *str;      // この代入は自然       p++;     }     str++;   }   *p = '\0'; } int main(void) {      //char *str;   //str = " 1 23 4 5";     (2)これでは空白を詰めた後の文字列が表示されないのはなぜか?      char str[] = " 1 23 4 5"; //これで OK   printf("空白を詰める前:\"%s\"\n", str);   TrimSpace(str);   printf("空白を詰めた後:\"%s\"\n", str);   return 0; }

  • C言語の穴埋め問題です

    次のプログラムは、初期化により文字列を定義し、辞書式配列にしたとき、どの文字列が先頭にくるかを調べるプログラムなのですが。■■■を教えてください #include <stdio.h> #include <string.h> #define N 5 //関数のプロトタイプ宣言 char *min(char *p[] , int n); int main(void) { char *p[N] = {"Hello" , "Hi" , "Happy" , "HaHaHa" , "Heaven"}; printf("辞書式配列で先頭となる文字列は%s\n" , ■■■); } char *min(char *p[] , int n) { int min; //最小値のアドレス Int i; //カウンタ min = 0; for(i = 1; i < n; i++){ if (strcmp(■■■ , ■■■) > 0){ ■■■= ■■■; } } return ■■■; }

  • 配列変数のアドレス

    C言語で、配列を宣言した場合、 char a[] = "hoge"; 変数aは初期化された配列の先頭番地を指しているのですが、この時、 変数aの中身も変数aのアドレス(&a)ともに上記の配列の先頭番地になっているようなのですが、 これによって、配列の変数aは読み取り専用で、書き換えられないということにしていると思っていいのでしょうか? ちなみに、 char *p = "fuga"; とした場合は、pと&pのアドレスは異なって、pの中身は書き換えられます。

  • C言語の型と配列

    char* str[10]={"a","b"}; char* str2="c"; としたときにstr=str2とすると 型が合わないといったエラーが出ます。 でもstrって結局はポインタの配列の先頭要素のアドレスですよね。 ポインタにポインタを入れているので通るのかなと思ったんですけど、 配列で宣言するとポインタにも型がつくのでしょうか? この例だと strは char * を10個持つ配列をさすポインタ  で、 str2はchar *をさすポインタ みたいなかんじです。 質問の意味がわかりにくいですが、ご指摘をいただければ補足しますので よろしくお願いします。

  • C言語で、ファイルを読み込んで数字と名前に分けて配列に格納に関する質問

    C言語で、ファイルを読み込んで数字と名前に分けて配列に格納に関する質問です! ファイルを開いた後でエラーとなるのですが、何が足りないのでしょうか? ファイル内容 20 田中 10 鈴木 #include <stdio.h> #include <string.h> #include <stdlib.h> int main(int argc,char *argv[]) { FILE *fp; char str[256]; char *tp; int k,i=0; int num[10]; char na[10][20]; fp=fopen(argv[1],"r"); if(fp==NULL){ printf("ファイルを開けません\n"); return 1; }else{ printf("開けた\n"); } while(fgets(str,sizeof str,fp)!=NULL){ tp=strtok(str," "); num[i]=atoi(tp); tp=strtok(NULL," "); strcpy(na[i],tp); i++; } printf("%d\n%s\n",num[0],na[0]); printf("%d\n%s\n",num[1],na[1]); fclose(fp); return 0; }

  • C言語の問題でわからない内容教えてください。

    C言語の問題でわからない内容教えてください。 #include <stdio.h> int main(void) { char a[3][6] = {"red","green","blue"}; char *b[4] = {"cyan","magenta","yellow","black"}; char *p = (char*) a; char **q = b; printf("%s\n",(p+1)); printf("%s\n",*(q+1)); } の中で  char **q = b;の部分は一度char *b[4] = {"cyan","magenta","yellow","black"}; でbをポインタで扱っているので、qを使用するときにポインタを使うときに**にしなければいけないと いうことなのでしょうか? 教えてください。 通常char b[4] = {"cyan","magenta","yellow","black"}; なら、char *q = b;になるのかということです。

専門家に質問してみよう