C++ operatorの使用について

このQ&Aのポイント
  • C++初心者がオペレーターの使用方法を勉強しています
  • 特定の文の処理を理解できず行き詰っています
  • オペレーターの処理順と結果の理解が必要です
回答を見る
  • ベストアンサー

C++ operatorの使用について

C++初心者で、現在オペレーターの使用方法について勉強しています。 下記プログラムの「 x = x + z;」箇所の処理について、理解できず行き詰っています。 初期化した際のx, y, zそれぞれの値が x = Help y = !e z = M となったところまでは、理解できています。 その後、x = x + zの処理に入る際、 1.abc operator+(abc) 2.void operator=(abc) の順でオペレーターの処理を行うと思います。 その際、1.はzを使用して処理をするところまでは分かるのですが、 return value: HelpM\n(\:バックスラッシュ)がx, y, zのどこに入るのか、 その後どのオブジェクトを持って2.の処理に入るのかどうか 理解できておりません。 初心者のため、文章がわかりづらい点等あるかと思いますが、 アドバイス頂けたら幸いです。 宜しくお願いいたします。 ========================================================================== #include <cstdio> #include <cstring> class abc { char def[21]; public: abc(void) { strcpy(def, "Help"); } abc(const char s[ ]) { strcpy(def, s); } abc(char c) { def[0] = c; def[1] = '\0'; } void operator=(abc); // redefines = between abc's!!! abc operator+(abc); void out( ) { printf("%s\n", def); } }; void abc::operator=(abc x) { int i, n = strlen(x.def); for(i = 0; i < n; i++) def[i] = x.def[n - (i + 1)]; def[n] = '\0'; } abc abc::operator+(abc a) { int i = 0; abc c; strcpy(c.def, def); while(c.def[i] != '\0') i++; for(int j = 0; a.def[j] != '\0'; j++) { c.def[i] = a.def[j]; i++; } c.def[i] = '\0'; return c; } int main( ) { abc x, y("!e"), z('M'); x = x + z; x.out( ); y = y + x; y.out( ); return 0; }

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

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

> デバック処理で追った結果、abc::operator+(abc a)を抜けた時点で、x.defが"HelpM"に変更されており、その後xを引数としてabc::operator=(abc x)へ処理しているように見えました。 そうですか? operator+の定義からすると、新たにcというオブジェクトを作成して、cにxの内容をコピーし、cに対してaの内容を結合したあとでcをreturnしていると思いますが。 > x=xから処理されないのは何故でしょうか。 演算子には優先順位というものがあります。代入演算=は加算演算子+よりも優先順位が低いため、+の方が先に処理されます。 算数で、1+2*3は2*3を先に計算すると教わりましたよね。それと同じように、演算子によって優先順位が付けられていて、順位の高いものから処理されます。順位が同じ場合には計算の方向が決められています。例えば、+を複数使用した式の場合、左から右へ処理すると決められているため、a+b+cはa+bを先に処理する、つまり(a+b)+cとして処理されます。代入演算子=の場合は逆に右から左と決められているため、a=b=1はb=1のあとでa=bが処理されます。

maple0823
質問者

お礼

優先順位について把握していなかったので、とても勉強になりました。 そして、処理の流れが理解でき、他のプログラムも問題なく読めました。 ご丁寧な回答をありがとうございました。

その他の回答 (1)

回答No.1

> return value: HelpM\n(\:バックスラッシュ)がx, y, zのどこに入るのか、 どこにも入りません。だって、そんな処理はコードに書かれていないでしょ。 x+zの結果は一時オブジェクトとして、既存のオブジェクトとは別に保持されます。 これは、クラスに限ったことではありません。 3つのdouble型変数a,b,cがあったとして、a+b+cを計算する場合に、まずはa+bを計算します。その結果はaにもbにもcにも入りませんよね。a+bの結果は一時的な変数に保存し、その値とcを加算します。

maple0823
質問者

補足

回答ありがとうございます。 デバック処理で追った結果、abc::operator+(abc a)を抜けた時点で、x.defが"HelpM"に変更されており、その後xを引数としてabc::operator=(abc x)へ処理しているように見えました。 >3つのdouble型変数a,b,cがあったとして、a+b+cを計算する場合に、まずはa+bを計算します。 >その結果はaにもbにもcにも入りませんよね。a+bの結果は一時的な変数に保存し、その値とcを加算します。 ⇒今回の、x = x + zは、x(z)をまず行い、x(x(z))を行っているように見えるのですが、 x=xから処理されないのは何故でしょうか。

関連するQ&A

  • C言語 シンプルソート

    C言語始めて1年の初心者です。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXSIZE 10000 void swapData(char *x, char *y); void simpleSort(char data[], int first, int last); int main(int argc, char *argv[]) { int data[MAXSIZE][300]; int i, j, count; FILE *fp; if(argc != 2) { fprintf(stderr, "Usage: %s <filename>\n", argv[0]); exit(0); } if ((fp = fopen(argv[1], "r")) == NULL) { fprintf(stderr, "File %s is not found.\n", argv[1]); exit(0); } for(i = 0; i < MAXSIZE; i++) { if (fscanf(fp,"%s", &data[i]) == EOF) break; } simpleSort(data[], 0, i - 1); for(j = 0; j < i; j++) printf("%s\n", data[j]); } void swapData(char *x, char *y){ char tmp[300]; strcpy(tmp, x); strcpy(x, y); strcpy(y, tmp); } void simpleSort(char data[], int first, int last) { int i, j; for(i = first; i < last; i++){ for(j = i+1; j <= last; j++){ if(strcmp(&data[i], &data[j]) > 0) swapData(&data[i], &data[j]); } } } 読み込んだ文字データをシンプルソートするプログラムなんですが、コンパイルできません。 simpleSortの部分がおかしいみたいなんですが、見直しても先入観からか間違いを見つけられません・・・・ どなたか間違いを指摘していただけたら助かります。

  • C言語に関して

    C言語に関して 100までの自然数を文字列に変換したいのですが、以下のプログラムを実行すると、001,002,…010,…099,100のようになってしまいます。左詰めにしたいのですが、どこが間違っているかご教示下さい。 #include <stdio.h> #define N1 100 #define N2 5 int get_ketasuu(); void henkankun(); int main(void) { int i, dig, x; int num1 = N1; int num2 = N2; int buff1[N1], buff2[N1]; char buff3[N1][N2]; for (i = 0; i < N1; i++) { x = buff2[i] = buff1[i] = i + 1; dig = get_ketasuu(x); henkankun(&buff2[i], &buff3[i], dig); printf("%s\n", buff3[i]); } return 0; } int get_ketasuu(x) int x; { int dig; dig = 0; do { x /= 10; dig++; } while (x > 0); return dig; } void henkankun(x, y, dig) int *x; int dig; char (*y)[N2]; { int j, k; switch (dig) { case 1 : k = 1; case 2 : k = 10; case 3 : k = 100; } j = 0; do { (*y)[j] = (*x / k) + '0'; *x %= k; k /= 10; j++; } while (k > 0); (*y)[j] = '\0'; }

  • C++のoperator関数でのキャストする場合の書き方がまだよく理解

    C++のoperator関数でのキャストする場合の書き方がまだよく理解できていません。 下記のコードで、 //ここから #include "stdafx.h" #include <string> #include <iostream> class AutoPtr { char *ptr; public: AutoPtr():ptr(0) { } ~AutoPtr() { delete [] ptr; } // char *operator=(char *ptr) { delete [] this->ptr; this->ptr = ptr; return this->ptr; } operator char *(){ return ptr; } char &operator[](int index) { return ptr[index]; } }; void reverse(char *str) { int i, n; AutoPtr work; n = strlen(str); work = new char[n+1]; strcpy(work, str); for(i=0; i<n; i++) { str[i] = work[n-i-1]; } printf("%s\n", str); } int _tmain(int argc, _TCHAR* argv[]) { char str[] = "ABCDEFG"; reverse(str); return 0; } //ここまで 2番目のoperator関数の定義ですが、 operator char *(){ return ptr; } これは多分、reverse()関数中の、 strcpy(work, str); のworkの展開に用いられると思うのですが、 機能としては、「operator char *」はAutoPtrをchar *にキャストするために使われているらしいのですが、何故この書き方でAutoPtrをchar *型にキャストできるのかがいまいち分かりません。また、2番目のoperator関数の記述「operator char *()」はどこまでが型で、どこからが関数の定義と見なせばよいのでしょうか? 何か勘違いしているかもしれません。理解されている方、御教示いただければと思っています。 よろしくお願い致します。

  • c言語の難しい問題について

    (c言語の問題) 下記のプログラムを完成させ、キーボードから文字列を読み込み、-1文字ずらすことによって暗号化を行うプログラムを作りなさい。ただし、ピリオド、空白などはそのままにするようにすること。 例)this is a pen. sghr hr @ qdm. #include<stdio.h> #define CHAR_NUM 256 void angou( I ) { II } int main(void) { unsigned char text[CHAR_NUM]; char moji; int i; puts("暗号化する文字を入力しなさい。"); while((moji=getchar()) !=EOF){ text[i]=moji; i++; } angou(text i); printf("%s",text); return(0); } I、IIに入る文を書きなさい。 私はIには「char x[],int y」 IIには 「if('A'<x[i]<'Z' && 'a'<x[i]<'z') int j; for(j=0;j<y;j++) x[j]=x[j]-1 else」 といれたのですが、出力がうまくでません。どうすればいいのですか?

  • C++のコンストラクタを使った自動ポインタでoperator関数の使い

    C++のコンストラクタを使った自動ポインタでoperator関数の使い方で分からないところがあります。 環境下はVisual C++でC/C++のWin32コンソールアプリケーションを使って行っています。 下記のコードで実行させています。やっていることは文字列を反転させて表示させるだけのことです。 #include "stdafx.h" #include <string> #include <iostream> class AutoPtr { char *ptr; public: AutoPtr():ptr(0) { } ~AutoPtr() { delete [] ptr; } // char *operator=(char *ptr) { delete [] this->ptr; this->ptr = ptr; return this->ptr; } operator char *(){ return ptr; } char &operator[](int index) { return ptr[index]; } }; void reverse(char *str) { int i, n; AutoPtr work; n = strlen(str); work = new char[n+1]; strcpy(work, str); for(i=0; i<n; i++) { str[i] = work[n-i-1]; } printf("%s\n", str); } int _tmain(int argc, _TCHAR* argv[]) { reverse("ABCDEFG"); return 0; } これを実行させると、reverse関数のfor()文の、str[i] = work[n-i-1];を実行させた所で実行エラーになってしまいます。その前の、strcpy(work, str);でworkにstrの内容が正常にコピーされているところまでは確認できています。operator関数の、 char &operator[](int index) { return ptr[index]; } で、operator[]はAutoPtrを配列のように扱っているはずなのですが、何故かstr[i] = work[n-i-1]; の所で実行エラーになってしまいます。 operaror関数の書き方が悪いのか、何が原因なのか分かりかねています。御経験のあるかたは、御教示いただけたらと思っています。 よろしくお願い致します。

  • C言語についてなのですが・・・

    さきほども上げたのですがカテゴリが間違っていたのでもう一回書き込みました まだプログラムの勉強をはじめた初心者なのですが、 テキストファイルから文字を読みこみ、大文字ならば小文字に変換し辞書順に並びかえるプログラムを作っているのですがどうしてもうまくいきません。 例えばtest.txtに XXX YYY YY XX BBB aaa aa BB とあれば aa aaa bb bbb xx xxx yy yyy と表示されるよにしたいんです。 自分が作ったプログラむはこれです。 まだテキストファイルからでなくキーボードからの入力になっていますが・・・ #include<stdio.h> #include<stdlib.h> #include<string.h> #include <ctype.h> int soto( const void *x, const void *y); int main(int argc, char *argv[]){ FILE *input; char str1[1000]; int i, j; for (i = 1; i < argc; i++){ qsort(argv[i], 1000, sizeof( char *), soto); strcpy(str1, argv[i]); for(j = 0; j < 100; j++){ str1[j] = tolower( str1[j] ); } printf("%s\n", str1); } return 0; } int soto( const void *a, const void *b){ char *x, *y; x = (char*)a; y = (char*)b; return x-y; } これだと小文字にはなるんですがソートされずに表示されてしまいます・・・ どのようにすればいけるのかご指摘のほどおねがいします

  • C言語の課題に取り組んでいるんですが・・・

    まだプログラムの勉強をはじめた初心者なのですが、 テキストファイルから文字を読みこみ、大文字ならば小文字に変換し辞書順に並びかえるプログラムを作っているのですがどうしてもうまくいきません。 例えばtest.txtに XXX YYY YY XX BBB aaa aa BB とあれば aa aaa bb bbb xx xxx yy yyy と表示されるよにしたいんです。 自分が作ったプログラむはこれです。 まだテキストファイルからでなくキーボードからの入力になっていますが・・・ #include<stdio.h> #include<stdlib.h> #include<string.h> #include <ctype.h> int soto( const void *x, const void *y); int main(int argc, char *argv[]){ FILE *input; char str1[1000]; int i, j; for (i = 1; i < argc; i++){ qsort(argv[i], 1000, sizeof( char *), soto); strcpy(str1, argv[i]); for(j = 0; j < 100; j++){ str1[j] = tolower( str1[j] ); } printf("%s\n", str1); } return 0; } int soto( const void *a, const void *b){ char *x, *y; x = (char*)a; y = (char*)b; return x-y; } これだと小文字にはなるんですがソートされずに表示されてしまいます・・・ どのようにすればいけるのかご指摘のほどおねがいします

  • C++超初心者質問

    Visual C++ 2008 Express Edition Ver9.0.30729.1 SP を利用し、以下のプログラムを実行するための手順を教えてください。 Visual C++ 6.0では、ファイル>新規作成→ファイルTAB>C++ソースファイルのように、上記の場合はどのように進んだらよいのでしょう? ファイル>新規作成>プロジェクト→Win32 コンソール アプリケーション??? とすると、↓のエラーが出てしまいます。尚、VC2008をインストールしてから何も触っていません。 http://okwave.jp/qa4665322.html ソース #include<iostream> using namespace std; class coord{ int x,y; public: coord(){x=0;y=0;} coord(int i,int j){x=i,y=j;} void get_xy(int &i,int &j){i=x;j=y;} friend coord operator+(coord ob1,int i); friend coord operator+(int i,coord ob1); }; coord operator+(coord ob1,int i){ coord temp; temp.x=ob1.x+i; temp.y=ob1.y+i; return temp; } coord operator+(int i,coord ob1){ coord temp; temp.x=ob1.x+i; temp.y=ob1.y+i; return temp; } int main(){ char c[3]; // 画面固定のため coord o1(10,10); int x,y; o1=o1+10;; o1.get_xy(x,y); cout<<"(o1+10)X:"<<x<<",Y:"<<y<<"\n"; o1=99+o1;; o1.get_xy(x,y); cout<<"(99+o1)X:"<<x<<",Y:"<<y<<"\n"; cout<<"\nエンターで抜けます"<<endl; // 画面固定のため gets(c); return 0; }

  • c言語 パスカルの三角形

    c言語でパスカルの三角形を出力するプログラムを作りたいのですが、上手くいきません。 何を直せばいいのか教えてください。 #include <stdio.h> #define N 10 int main(void){ int i, j = 1, x, y; int d[N][N]; /* 三角形を作成 */ for (i = 1 ; i < N ; i++){ d[i][0] = 1; while (j <= i - 1){ d[i][j] = d[i-1][j-1] + d[i-1][j]; j ++; } } /* 三角形の表示 */ for (y = 0; y < N; y++) { for (x = 0; x < N-y; x++) printf(" "); for (x = 0; x < y; x++) printf("%3d ", d[x][y]); printf("\n"); } return 0; } 実行結果 -2147417616 2665208 1629976532 1627572249 1629101723 1 1629982744 2665256 2665548 3407923 1629345053 1627571017 0 3538997 1629739051 10 1629345053 2665368 3670071 2665384 1629739040 1627927140 2665244 1628040295 57 1628810863 1629476960 1628602749 2665560 2665304 1629345053 0 1629739040 1629740576 1628992224 2 4411498 1628040588 -2147417600 0 1629476960 1629740664 1629739040 1 267574 0

  • C言語。どうしてコンパイルできません^^;

    最近プログラミングの勉強をはじめました。 C言語を勉強しています。 /*入力した値の、平均値・最大値・最小値・を出す。*/ #include <stdio.h> int main(void) { int x[5],i,j,w,x,y,z,sum; printf("5つの実数の平均、最大値、最小値を求めます\n"); sum = 0; for(i=0; i<5; i++){ printf("値%d:",i+1); scanf("%d",&x[i]); sum += x[i]; } for(y=0; y<5; y++){ for(j=0; j<4; j++){ w=j+1; if(x[j] < x[w]){ z = x[i]; x[i] = x[w]; x[w] = z; } } } printf("平均値:%f\n最大値:%d\n最小値:%d\n", (double)sum/5, x[0], x[4]); return 0; } Microsoft Visual C++ 2008 Express Edition でコンパイルをしようとしたのですが、 「error C2040: 'x' : 'int' は 'int [5]' と間接操作のレベルが異なります。」 と出てできませんでした^^; 何度も見直したのですが、どうしても間違っている場所がわかりません^^; どこがいけないのでしょうか^^;

専門家に質問してみよう