• ベストアンサー

Sizeofが分かりません

sizeofのデータサイズがどういう風に計算されているのかよく分かりません。 例えば以下のコードですが、 union Name { char firstName[10]; char lastName[10]; }; int main() { union Name name; strcpy(name.firstName, "Dennis"); strcpy(name.lastName, "Ritchie"); printf("%d", sizeof(name)); } outputは11となります。これはなぜでしょうか? 宜しくお願い致します。

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

  • ベストアンサー
回答No.5

これはunionが分からないのではないでしょうか? unionは同じ場所を名前や型を代えて宣言する方法ですよね? name.firstName.[0]もname.lastName.[0]も全く同じ場所のデータですよ。 一番大きなサイズが取られますが先頭は同じ場所です。 例えば union Person { char cFirstName[10]; char cLastName[10]; char cAddress[255]; } で終端コードまで計算するコンパイラならsizeof(Person)は256です。 通常は255です。 cFirstName[0]を'A'に変えたら、cLastName[0]もcAddress[0]も'A'に変わります。 Unionですから。 structを使えば、期待するサイズが得られるのではないでしょうか?

codingbeginner
質問者

お礼

sizeofが分からないと思っていましたが、unionが分かっていないのではと気付いて解説して下さったTreatMeGentlyさんをベストアンサーにしたいと思います。ありがとうございました!

その他の回答 (4)

  • tsunji
  • ベストアンサー率20% (196/958)
回答No.4

unionで宣言すると共用体になるので10ですね。 structの構造体宣言なら20になります。 プログラムからするとstructの間違いでは? http://www.comb.kokushikan.ac.jp/~ken/blogn/sb/c/archives/2005/02/post_8.html

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

「よくわかりません」ということだけど, どこまでわかってどこで困っているのですか? そもそも sizeof が何をするものかは理解できていますか?

  • maiko0318
  • ベストアンサー率21% (1483/6970)
回答No.2

sizeof演算子は、データ型や構造体で確保した記憶領域の大きさを、 整定数のバイト数で表すものです。通常、この記憶領域の大きさの計算はコンパイル時に行われます。 ~はじめての”C”より~ コンパイル時に行われるということは、実行時に何を代入しようが、 どのようにメモリーを壊そうが関係ないということです。 コンパイル時ということですから、コンパイル後のコードを見ると、 printf("%d", sizeof(name));  ではなく、 printf("%d", 10);       となっています。

codingbeginner
質問者

お礼

そうですね。10になりますよね。11は正解を見間違いしていました。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.1

コードを載せるときは、回答しようとする側で そのままコンパイルできるよう、極力省略しないでいただければ、 と思います。 さて、私のところで下記のコードを実行したところ、 10 という結果を得ました。 #include <stdio.h> #include <string.h> union Name { char firstName[10]; char lastName[10]; }; int main(void) { union Name name; strcpy(name.firstName, "Dennis"); strcpy(name.lastName, "Ritchie"); printf("%s\n", name.firstName); printf("%s\n", name.lastName); printf("%d\n", sizeof(name)); return 0; }

codingbeginner
質問者

お礼

余分なものは省略した方がシンプルで見やすいかなと思いました。以後気を付けます。

関連するQ&A

  • sizeof

    main() { char array1[256] = "abcdefg"; char *array2 = "stuvwxyz"; printf("array1 = %d\n",sizeof(array1)); // array1 = 256 printf("array1 = %d\n",sizeof(array1)/sizeof(char)); // array1 = 256 printf("array2 = %d\n",sizeof(array2)); // array2 = 4 printf("array2 = %d\n",sizeof(array2)/sizeof(char *)); // array1 = 1 printf("array2 = %d\n",sizeof(*array2)); // array2 = 1 } となるのですが、sizeof(array1)では、配列のサイズが取得できるのですが、array2がさす配列のサイズを得るためにはどうすればいいのですが?もしくは取得デキナイのはなぜでしょうか。 それと、 sizeof(array2)では、charへのポインタをさすから4バイト。 sizeof(*array2)では、sizeof(array[0])を意味するから1バイト という解釈でいいでしょうか。

  • sizeof()の使い方

    あるプログラムでちょっと珍しいソースコードがありました。 *************************************************************** int x[7]; int nx = sizeof(x) / sizeof(x[0]); for (i = 1; i < nx; i++) { -省略- } *************************************************************** sizeof()という珍しい関数を使っています。 このプログラムの目的は、sizeof()を使って、forの繰り返し回数を算出して、 プログラマー側がアルゴリズムを考えて、forの繰り返し回数を設定する手間を省いてくれることにあります。 しかし、ちょっとおかしな事がありまして、 printf("sizeof(x)="); printf("%d\n",&sizeof(x)); printf("sizeof(x[0])="); printf("%d\n",&sizeof(x[0])); printf("nx=sizeof(x) / sizeof(x[0]):"); printf("%d\n",&nx); を使って、sizeof(x),sizeof(x[0]),nxに何が設定されたかを確かめたところ、 sizeof(x)=28 sizeof(x[0])=7 nx=1638196 と分かりました。nxは”7”でないとおかしいと思うのですが、いかがでしょうか?

  • ポインタのsizeofについて

    C初心者です。 ポインタ宣言させた変数をsizeof()で値を取得させて 表示させてみました。 char *cp; short int *sp; int *ip; i = sizeof(cp); printf("%d\n",i); i = sizeof(sp); printf("%d\n",i); i = sizeof(ip); printf("%d\n",i); 結果は全て4となりました。 これはなぜですか? (ただの変数として宣言すれば1、2、4となります。この理由も理解できています。)

  • 正しいsizeofの使い方とcharのポインタについて教えてくださいm(__)m

    C言語なのですが、 例えば、次のように実験してみました。 char * rec_fld[12]; int x,y; char tt[11]; ※rec_fld[1]には”私は完全な素人” という文字が入っていると思ってください。 x = sizeof( rec_fld[1] ); strcpy( tt, rec_fld[1] ); y = sizeof( tt ); すると、xは4とかいう数字が格納されていて、 yには11という数字が格納されていました。 ttが11なのは分かりやすいのですが、 なんで、xは、文字数の14とかにならないのでしょうか? sizeofの中の書き方が違うのでしょうか? あと、char *で配列宣言するのと、charで宣言するのとは 何が違うのでしょうか? どなたか、教えて下さいませ。

  • 次のようにセットされている文字列を出力するプログラムを作成したのですが

    次のようにセットされている文字列を出力するプログラムを作成したのですが、引数を渡すことができません。まだ、初心者でどこがいけないかが分かりません。ご教授をお願いいたします。 int _tmain(int argc, _TCHAR* argv[]) { int a=0; char name_main[50]; set_name(name_main); printf( "セットされている名前は%sです", name_main ); return 0; } void set_name(char *name) { int n=0; char *str=NULL; char str2[50] = "yamada taro"; str = (char*) malloc( sizeof(char) * 50); memcpy( str, str2, 50 );

  • java これはオーバーロードすればいいのでは?

    以下のようなコードについて質問です。 class Person { public static int count = 0; public String firstName; public String middleName; public String lastName; public int age; public double height; public double weight; Person(String firstName, String lastName, int age, double height, double weight) { Person.count++; this.firstName = firstName; this.lastName = lastName; this.age = age; this.height = height; this.weight = weight; } Person(String firstName, String middleName, String lastName, int age, double height, double weight) { this(firstName, lastName, age, height, weight); this.middleName = middleName; } public String fullName() { if(middleName == null){ return this.firstName + " " + this.lastName; }else{ return this.firstName + " "+middleName+ ""+ this.lastName; } } fullName() メソッドを条件分岐して、以下のようなメソッドで、ミドルネームを入れるかどうかで、条件分岐するということなのですが… class Main { public static void main(String[] args) { Person person1 = new Person("Kate", "Jones", 27, 1.6, 50.0); person1.printData(); Person person2 = new Person("John", "Christopher", "Smith", 65, 1.75, 80.0); person2.printData(); Person.printCount(); } } これって、引数にfullNameメソッドに何も指定してなくていいのでしょうか。 疑問に感じてしまいました。 また、同じfullNameメソッドという名前のメソッドで引数でmiddleNameの有無だけ変えてオーバーロードしてはだめなのでしょうか。

  • char型+char型ってint型? if(char型==int型)?

    C言語の「汎整数拡張(インテグラルプロモーション)」というものに関するものだと思います。 char型とchar型を加えた結果は、char型でしょうか。それともint型でしょうか。 (下のプログラムの printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */ という部分の結果は4なので、int型と考えるべきなのかな。) 私は、char型とint型の加算の結果はint型だと思っていましたが、 char型とchar型の加算の結果はやはりchar型だと思っていました。 (それが間違えているのでしょうか。) if(a[0]==i) /* char型とint型の比較(?) */ の部分では、左辺はchar型、右辺はint型ですが、このように型の違う変数を比較しても文法上構わないのでしょうか。 (私は、「比較は必ず型の同じもの同士でしかできない」と思っていました。) 左辺はchar型のように見えて、じつはint型ですか。 #include <stdio.h> int main(void) { char a[4]; int i=77; printf("sizeof(int)は%d\n", sizeof(int)); printf("sizeof(char)は%d\n", sizeof(char)); printf("sizeof('M')は%d\n", sizeof('M')); printf("sizeof(a[0])は%d\n", sizeof(a[0])); a[0]='M'; a[1]=7+6; a[2]=a[0]+a[1]; printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */ printf("sizeof(+a[0])=%d\n", sizeof(+a[0])); if(a[0]==i) /* char型とint型の比較(?) */ puts("a[0]==i"); else puts("a[0]!=i"); return(0); } ちなみにワーニングもエラーもなんにもでません。

  • (Mac) sizeof演算子のコンパイル

    現在MacBookAirにて入門書を参考にC言語を学んでいます。 その中で、 #include <stdio.h> int main(void) { int a = 1; printf("short int型のサイズは%dバイトです。\n", sizeof(short int)); printf("変数aのサイズは%dバイトです。\n", sizeof(a)); return 0; } と入力しコンパイルすると sample21.c:7: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long unsigned int’ sample21.c:8: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘long unsigned int’ と表示されコンパイルすることができません。 なんども見直してコードに間違いはないと思いますが、原因が解りません。 他のコードは問題なくコンパイルできます。 この先、sizeof演算子を使って値を求めなければならない章があり、非常に困っています。 どなたか解決策を教えてください。お願いします。

  • 一番大きい奇数を表示する

    scanf関数を使って数字を10回入力して一番大きなものを表示させるプログラムをつくったのですが、 さらに一番大きな奇数を表示するにはどうすればいいのでしょうか? 偶数=割り切れる 奇数=割り切れない というところまでは分かるのですが、以下のプログラムに奇数を判別するソースを追加するのにはどうすればいいのでしょうか。 #include <stdio.h> int main(void) { char str[1024]; char buf[10]; int i; int w; printf("文字列を10回入力して下さい:\n"); memset(str, 0, sizeof(str)); for (i = 0; i < 10; i++) { memset(buf, 0, sizeof(buf)); printf("input>\n"); scanf("%s", buf); } for (i = 0; i < 10; i++) { if ((buf[i] & 1) == 1) /* 奇数であるか */ { if (strcmp(buf, str) > 0) { strcpy(str, buf); } } } printf("output>\n%s\n" , str); getchar(); }

  • 動的なメモリ管理

    下記のプログラムで、確保したメモリブロックをどこで開放していいかわかりません。教えてください。お願いします。 #include <stdio.h> #include <string.h> #include <stdlib.h> #define BUFFERSIZE 11 #define MAX_PERSON 10 #define MAX_CHARS 10 int main(void){ char *name[10]; //氏名 int count; int i; int l; //文字列の長さ int top_index = 0; int bot_index; char *tmp; printf("*** 入力された氏名をソートし、表示します ***\n"); printf("*** 最大入力件数10件(1文字目'0'で入力終了) ***\n"); putchar('\n'); for (i = 0; i < MAX_PERSON ; i++) { printf("氏名入力(10文字まで有効) > "); name[i] = malloc(sizeof(char) * BUFFERSIZE); fgets( name[i], BUFFERSIZE, stdin); l = strlen(name[i]); if (name[i][l-1] == '\n'){ name[i][l-1] = '\0'; } else { while ( getchar() != '\n'){ } } if (name[i][0] == '0'){ break; } printf("累計 : %d\n", i+1); } count = i; //ソート前 /*printf("ソート前\n"); for (i = 0 ;i < count ; i++ ){ printf("%s\n", name[i]); } */ bot_index = count -1; //シェーカーソート while (1) { int last_swap_index; // 順方向のスキャン last_swap_index = top_index; for ( i = top_index; i < bot_index; i++){ if(strcmp(name[i],name[i+1]) > 0 ){ //ポインタ配列の要素の交換 tmp = name[i]; name[i] = name[i+1]; name[i+1]=tmp; //実体交換 //tmp = (char*)malloc((strlen(name[i])+1)*sizeof(char)); //strcpy(tmp,name[i]); //strcpy(name[i],name[i+1]); //strcpy(name[i+1],tmp); last_swap_index = i; } } //後方のスキャン範囲を狭める bot_index = last_swap_index; if (top_index == bot_index){ break; } // 逆方向のスキャン last_swap_index = bot_index; for ( i = bot_index; i > top_index; i--){ if(strcmp(name[i],name[i-1]) < 0 ){ //実体交換 //tmp = (char*)malloc((strlen(name[i])+1)*sizeof(char)); //strcpy(tmp,name[i]); //strcpy(name[i],name[i-1]); //strcpy(name[i-1],tmp); //要素の交換 tmp = name[i]; name[i] = name[i-1]; name[i-1]=tmp; last_swap_index = i; } } //前方のスキャン範囲を狭める top_index = last_swap_index; if (top_index == bot_index){ break; } } printf("+++++データ表示+++++\n"); for (i = 0 ;i < count ; i++ ){ printf("%2d : %s\n", i+1, name[i]); } return 0; }

専門家に質問してみよう