• ベストアンサー

プログラムの関数化

ibe_tattsuの回答

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

お返事ありがとうございました。 先ほどは、プログラムをよく検証せずに方法のみで返事をさせていただいたのですが、 よくよく見ると、このプログラムは正常に動くのでしょうか? 実際に引数を入力して動かしてみると、 #a.out 3 - 1 3 - 1 = 3 0 となりました。正しい結果じゃないですね^^; 上手く動作しないということ以外でなければ、プログラムを提示するときは、動作を一応確認しておいてください。 今回の質問者さんの目的は関数化ですし。 それとこの質問から見始めた方もいると思うので、プログラムの仕様なども記載しておくべきと思います。 >ちなみに少しだけ関数化させてみたのですが、あまり意味のない関数化だと思い、全く自信がありません。 経験がなければ、自信が無いのは普通です。経験と共にきれいなプログラムが書けるようになってきますし、 最初はメイン関数のみになるというのも普通のことです。 今回、関数化されているところは私は適切だと思いますし、 まずはできるだけ自信を持って、自分なりにやってみてください。

teru3128
質問者

お礼

一応オーバーフローも考慮して、ちゃんと動くようになりましたよ。 開発環境はvc2005です。ファイル名 オペランド 演算子 オペランド と入力して実行すればちゃんと動きますよ! <<今回、関数化されている部分は適切 ありごとうございます。少しずつ関数になれていきたいと思います。

teru3128
質問者

補足

失礼しました。確認したところ確かにバグがありました。 case '/' : /* 0による除算 */ if ( rop == 0 ) { printf ( "error : 0による除算は禁止です。\n" ); exit ( -1 ); } overflow_check4(); result = lop % rop; // 剰余を求める /* 割り算の結果として余りが出なかった場合 */ if ( result == 0 ) { result = lop / rop; printf ( "%d %c %d = %d", lop, op, rop, result ); exit ( 0 ); /* 割り算の結果として余りが出た場合 */ } else { result = lop / rop; mod = lop % rop; printf ( "%d %c %d = %d余り%d", lop, op, rop, result, mod ); exit ( 0 ); } break; default: printf ( "error : '+' '-' '*' '/'のいずれかの演算子を入力して下さい。\n" ); exit ( 0 ); } /* 数値1 演算子 数値2 = 演算結果の形式で出力する */ printf ( "%d %c %d = %d", lop, op, rop, result ); exit ( 0 ); } ちなみに掛け算のオーバーフローのコードが間違っている気が するのですが、これで正しいのでしょうか?

関連するQ&A

  • 加減剰余のオーバーフローについて

    今C言語で加減剰余のプログラムを作っていて、 オーバーフローのチェックだけが上手くいきません。 limits.hをインクルードして、オーバーフローのチェック を行いたいのですがどうすればよいのでしょうか? 扱いたい範囲はint型の-2147483648~2147483647です。 ちなみに開発環境はvc++2005です。 一応ソースを載せておきますので、よろしくお願いします。 #pragma warning ( disable : 4996 ) #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <limits.h> int main ( int argc, char *argv[] ) { int start; // 最初に入力する値(引数1) int end; // 最後に入力する値(引数3) int kekka; // 計算結果を格納 int amari; // 除算の余りを格納 int max = INT_MAX; // 表すことが出来る最大値 int min = INT_MIN; // 表すことが出来る最小値 char enzansi; // 入力する演算子 (引数2) char str1[512]; // 格納用の配列を宣言(start用) char str2[512]; // 格納用の配列を宣言(end用) /* 引数の個数チェック */ if ( argc != 4 ) { printf ( "usage : %s start enzansi end\n", argv[0] ); exit ( 0 ); } /* 引数を取得して整数型に変換 */ start = atoi ( argv[1] ); end = atoi ( argv[3] ); /* 引数の取得 */ enzansi = ( argv[2][0] ); sprintf ( str1, "%d", start ); // str1に値を格納 sprintf ( str2, "%d", end ); // str2に値を格納 /* str1とargv[1]による文字列の比較 */ if ( strcmp ( str1, argv[1] ) ) { printf ( "error : 整数を入力して下さい。\n" ); exit ( 0 ); /* str2とargv[3]による文字列の比較 */ } else if ( strcmp ( str2, argv[3] ) ) { printf ( "error : 整数を入力して下さい。\n" ); exit ( 0 ); /* argv[2]が2文字以上の場合 */ } else if ( strlen ( argv[2] ) >= 2 ) { printf ( "error : 演算子を正しく入力して下さい。\n" ); exit ( 0 ); } /* 入力された演算子の条件ごとに計算 */ if ( enzansi == '+' ) { kekka = start + end; } else if ( enzansi == '-' ) { kekka = start - end; } else if ( enzansi == '*' ) { kekka = start * end; } else if ( enzansi == '/' ) { /* startの値を0で除算する場合 */ if ( end == 0 ) { printf ( "error : 0による除算は禁止です。\n" ); exit ( 0 ); } kekka = start % end; // 剰余を求める /* 割り算の結果として余りが出なかった場合 */ if ( kekka == 0 ) { kekka = start / end; printf ( "%d %c %d = %d", start, enzansi, end, kekka ); exit ( 0 ); /* 割り算の結果として余りが出た場合 */ } else if ( kekka != 0 ) { kekka = start / end; amari = start % end; printf ( "%d %c %d = %d余り%d", start, enzansi, end, kekka, amari ); exit ( 0 ); } /* 入力された演算子が異なる場合 */ } else { printf ( "error : '+' '-' '*' '/'のいずれかの演算子を入力して下さい。\n" ); exit ( 0 ); } /* 数値1 演算子 数値2 = 演算結果の形式で出力する */ printf ( "%d %c %d = %d", start, enzansi, end, kekka ); exit ( 0 ); } もし変な部分がありましたら指摘お願いします。 一応四則演算は問題なくできます。

  • ソースプログラムのエラー

    自分で四則演算のプログラムを組んだのですが エラーが出てお手上げ状態です。 どこが間違っているのかどなたか教えていただけませんか?? ちなみに足し算の場合はいくつ足しても計算できるという プログラムです☆ #include<stdio.h> int main(int argc, char *argv[]){ int i,a=0,b=0,x=0; int m=0; if(argv[1]!="+"||argv[1]!="-"||argv[1]!="*"||argv[1]!="/"||){ printf("指定された文字ではありませんよ\n"); return -1; } a = atoi(argv[2]); b = atoi(argv[3]); if(argv[1]=="-"){ m=a-b; } if(argv[1]=="*"){ m=a*b; } if(argv[1]=="/"){ m=a/b; } if(argv[1]=="+"){ for(i=2;i<argc;i++){ x=atoi(argv[i]); m+=x; } printf("%d\n",m); return 0; }

  • プログラムがバグっている箇所を教えて下さい(1)

    C++初心者です。 以下のソースコードでバグっていると思われる箇所を教えていただけるとありがたいです。 /* 02_LIFO.cpp * * int型整数を格納するスタックを、配列を用いて実現する(格納上限1000個) * */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "02_LIFO.h" /* スタック格納要素最大数実装 */ const int LIFO::m_maxSize = 1000 * sizeof(int); /* コンストラクタ */ LIFO::LIFO() { memset(m_stack, 0, m_maxSize); } /* デストラクタ */ LIFO::~LIFO() { /* nop */ } /* プッシュ */ int LIFO::LIFO_push_array(const int push_value) { if (m_stored > m_maxSize) { return EXIT_FAILURE; } else { m_stack[m_stored++] = push_value; return EXIT_SUCCESS; } } /* ポップ */ int LIFO::LIFO_pop_array(int *pop_value) { if (m_stored == 0) { return EXIT_FAILURE; } else { *pop_value = m_stack[m_stored--]; return EXIT_SUCCESS; } } /* 以下テスト用 */ static void Check(bool result, int line) { if (result == false) { /* 結果がおかしい処理の行をログ出力 */ printf("ERROR Line:%d\n", line); } } /* 正常系テスト */ static void TestNormal(void) { int result; LIFO stack; result = stack.LIFO_push_array(10); Check((result == EXIT_SUCCESS), __LINE__); result = stack.LIFO_push_array(20); Check((result == EXIT_SUCCESS), __LINE__); int val = 0; result = stack.LIFO_pop_array(&val); Check((result == EXIT_SUCCESS), __LINE__); Check((val == 20), __LINE__); result = stack.LIFO_pop_array(&val); Check((result == EXIT_SUCCESS), __LINE__); Check((val == 10), __LINE__); } /* 境界値テスト */ static void TestLimit(void) { int result; LIFO stack; /* 空の状態でPOP */ int val = 0; result = stack.LIFO_pop_array(&val); Check((result == EXIT_FAILURE), __LINE__); /* MAX値までPUSH */ for (int i = 0; i < 1000; i++) { result = stack.LIFO_push_array(10); Check((result == EXIT_SUCCESS), __LINE__); } /* MAX値を超えてPUSH */ result = stack.LIFO_push_array(10); Check((result == EXIT_FAILURE), __LINE__); } /* メイン関数 */ int main() { /* テスト */ printf("TestStart\n"); TestNormal(); TestLimit(); printf("TestEnd\n"); return 0; }

  • scanf関数のプログラムをgetchar関数で

    scanf関数を使って四則演算、論理輪、論理積をint、float、double型で表示するプログラムを作ったのですが これをscanf関数ではなく、getchar関数で組みなおし、関数化する課題が出ました。 そのままscanf関数のところだけを変えても型が違うというエラーが出てうまくいきません。 どうすればいいでしょうか? 一応scanf関数で組んだプログラムの一部を載せておきます。 #include <stdio.h> #include <math.h> main() { float a , b; float x[5]; printf("正の数字を2つ入力して下さい(小数点を含めて4ケタまで):\n"); for(;;) { printf("\na="); scanf("%f" , &a); if(a>=0 && a<=9999 && a) { break; } else { printf("****aに入力エラー****\n"); printf("数字は4ケタ以内の正数を入力:\n"); continue; } } for(;;) { printf("b="); scanf("%f" , &b); if(b>=0 && b<=9999 && b) { break; } else { printf("****bに入力エラー****\n"); printf("数字は4ケタ以内の正数を入力:\n"); continue; } } x[0] = a+b; x[1] = a-b; x[2] = a*b; x[3] = a/b; x[4] = a||b; x[5] = a&&b; printf("\n"); printf("int型 結果:\n足し算=%d\n" , (int)x[0]); printf("引き算=%d\n" , (int)x[1]); printf("掛け算=%d\n" , (int)x[2]); printf("割り算=%d\n" , (int)x[3]); printf("論理和=%d\n" , (int)x[4]); printf("論理積=%d\n" , (int)x[5]); printf("\n"); printf("float型 結果:\n足し算=%f\n" , x[0]); printf("引き算=%f\n" , x[1]); printf("掛け算=%f\n" , x[2]); printf("割り算=%f\n" , x[3]); printf("論理和=%f\n" , x[4]); printf("論理積=%f\n" , x[5]); ・ ・ ・ getchar(); }

  • プログラムがバグっている箇所を教えて下さい(2)

    C++初心者です。 以下のソースコードでバグっていると思われる箇所を教えていただけるとありがたいです。 /* LIFO_04.cpp * * int型整数を格納するスタックを、配列を用いて実現する * メモリ確保処理回数を少なくするために、512*N個の格納時にメモリを確保する * */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include "LIFO_04.h" #define DEBUG #ifdef DEBUG static int newCount = 0; /* mallocのコール回数 */ static int resizeCount = 0; /* reallocのコール回数 */ static int deleteCount = 0; /* freeのコール回数 */ #endif LIFO_04::LIFO_04() : m_pStack(0), m_stored(0) { #ifdef DEBUG newCount = 0; resizeCount = 0; deleteCount = 0; #endif } LIFO_04::~LIFO_04() { /* nop */ } int LIFO_04::LIFO_push_array(const int push_value) { int result = PreProcess(); if (result == EXIT_SUCCESS) { m_pStack[m_stored++] = push_value; } return result; } int LIFO_04::LIFO_pop_array(int *pop_value) { int result; if (m_stored <= 0) { /* スタック空 */ result = EXIT_FAILURE; } else { *pop_value = m_pStack[--m_stored]; result = PostProcess(); } return result; } /* 指定バイト境界に値を切り上げる */ int LIFO_04::RoundUp(int val, int align) { if (val > 0) { return (((val - 1) / align) + 1) * align; } else { return val / align * align; } } /* 事前処理 */ int LIFO_04::PreProcess(void) { int result; if (m_stored == 0) { /* スタック新規作成 */ m_pStack = new int[m_blockLen]; #ifdef DEBUG newCount++; #endif } else if (m_stored % m_blockLen == 0) { /* スタック領域拡大 */ int resize = RoundUp(m_stored, m_blockLen * sizeof(int)); int* pBuf = ResizeBlock(m_pStack, resize); if (pBuf != 0) { m_pStack = pBuf; } } else { /* nop */ } return (m_pStack != 0) ? EXIT_SUCCESS : EXIT_FAILURE; } /* 事後処理 */ int LIFO_04::PostProcess(void) { int result; if (m_stored <= 0) { /* スタックが空になった */ delete m_pStack; #ifdef DEBUG deleteCount++; #endif m_pStack = 0; result = EXIT_SUCCESS; } else if (m_stored % m_blockLen == 0) { /* 領域縮小 */ int* pBuf = ResizeBlock(m_pStack, m_stored); if (pBuf != 0) { m_pStack = pBuf; result = EXIT_SUCCESS; } } else { result = EXIT_SUCCESS; } return result; } /* ブロックサイズを変更する */ int* LIFO_04::ResizeBlock(int* pBlock, int resize) { int* pBuf = new int[resize]; /*int* pBuf = (int*)(realloc(m_pStack, sizeof(int) * resize));*/ #ifdef DEBUG resizeCount++; #endif if (pBuf != 0) { /* 新たに確保したメモリへコピーして、元の領域を開放 */ memcpy(pBuf, pBlock, resize); delete pBlock; } return pBuf; } /* 以下評価用 */ #ifdef DEBUG static void Check(bool result, int line) { if (result == false) { printf("ERROR Line:%d\n", line); } } static void TestNormal(void) { int result; LIFO_04 stack; result = stack.LIFO_push_array(10); Check((result == EXIT_SUCCESS), __LINE__); Check((newCount == 1), __LINE__); result = stack.LIFO_push_array(20); Check((result == EXIT_SUCCESS), __LINE__); int val = 0; result = stack.LIFO_pop_array(&val); Check((result == EXIT_SUCCESS), __LINE__); Check((val == 20), __LINE__); result = stack.LIFO_pop_array(&val); Check((result == EXIT_SUCCESS), __LINE__); Check((val == 10), __LINE__); Check((deleteCount == 1), __LINE__); Check((resizeCount == 0), __LINE__); } static void TestLimit(void) { int result; LIFO_04 stack; /* 空の状態でPOP */ int val = 0; result = stack.LIFO_pop_array(&val); Check((result == EXIT_FAILURE), __LINE__); /* m_blockLen値までPUSH */ for (int i = 0; i < 512; i++) { result = stack.LIFO_push_array(10 + i); Check((result == EXIT_SUCCESS), __LINE__); } Check((deleteCount == 0), __LINE__); Check((resizeCount == 0), __LINE__); /* m_blockLen値を超えてPUSH */ result = stack.LIFO_push_array(20); Check((result == EXIT_SUCCESS), __LINE__); Check((resizeCount == 1), __LINE__); result = stack.LIFO_pop_array(&val); Check((result == EXIT_SUCCESS), __LINE__); Check((val == 20), __LINE__); result = stack.LIFO_pop_array(&val); Check((result == EXIT_SUCCESS), __LINE__); Check((val == 10 + 511), __LINE__); } #endif int main() { #ifdef DEBUG printf("TestStart\n"); TestNormal(); TestLimit(); printf("TestEnd\n"); #endif return 0; }

  • 並べ替えのプログラム

    整数を20個入力し、まずそのまま表示してその後大きい順に並べ替えて表示するプログラムを作っているのですが、最大値しか表示されません。多分for文の3重ループの中がおかしいと思うのですがよくわかりません。 #include <stdio.h> int main(int argc, char* argv[]) { int c,i,x,max; int sav = 0; int before[20]; int after[20]; int check[20] = {0}; printf("整数を20個入力してください: "); for(i = 0; i < 20; i++) { scanf("%d",&before[i]); } printf("\n"); printf("BEFORE\n"); for(i = 0; i < 20; i++) { printf("%d\n",before[i]); } printf("\n"); max = 0; for(c = 0; c < 20; c++) { for(x = 0; x < 20; x++) { for(i = 0; i < 20; i++) { if(before[i] > max && check[i] == 0) max = before[i]; sav = i; } if(check[sav] == 0) check[sav] = 1; after[19 - x] = max; } } printf("AFTER\n"); for(x = 0; x < 20; x++) { printf("%d\n",after[x]); } return 0; } よろしくお願いします。

  • プログラムのフローチャートがかけません。

    次のプログラムのフローチャート(流れ図)を書いてください。お願いします。 フローチャートの書き方は以下のwebから見れます。 http://sasuke.main.jp/furo.html #include<stdio.h> #include<math.h> #include<stdlib.h> #define MAX_DATA_NUMBER 400 int check_value(int x, char* error_message); int main(int argc ,char*argv[]){ int M=0 ,i=0,N,U double x[2][MAX_DATA_NUMBER],y_bunshi FILE *in_file; in_file = fopen(argv[1],"r"); M = 0; if(argc != 3){ printf("使い方: ./smooth 入力データファイル名 平滑化数N"); exit(1); } N = check_value(atof(argv[2]),"平滑化数は正の値を入力してください。\n使い方: ./smooth 入力データファイル名 平滑化数N"); if(argc == 3){ if( in_file == NULL){ printf("使い方: ./smooth 入力データファイル名 平滑化数"); exit(1); } } while( EOF != fscanf(in_file, "%lf", &x[0][M]) && M<MAX_DATA_NUMBER){ M++; } fclose(in_file); for(i=0;i<=N-1;i++){ y_bunshi = 0; for(U=0;U<=i+N;U++){ y_bunshi += x[0][U]; } x[1][i] = y_bunshi/(i+N+1); } for(i=N;i<M-N;i++){ y_bunshi = 0; for(U=1;U<=N;U++){ y_bunshi += x[0][i+U]; y_bunshi += x[0][i-U]; } y_bunshi += x[0][1]; x[1][i] = y_bunshi/(2*N+1); } for(i=M-N;i<=M-1;i++){ y_bunshi = 0; for(U=i-N;U<=M-1;U++){ y_bunshi += x[0][U]; } x[1][i] = y_bunshi/(M+N-i); } for(i=0;i<M;i++){ printf("%3d,%8.2f,%8.3f\n",i,x[0][i],x[1][i]); } return 0; int check_value(int x,char* error_message){ if( x <= 0.0){ printf(error_message); exit(1); return x; }

  • プログラム問題(3)

    以下の問題のプログラムをやったのですが、コマンドプロンプトで実行してみるとエラーになってしまうのですが、どなたか問題点を指摘していただけないでしょうか? 【問題】 3桁の整数の値を入力していき、-9999が入力されたところで、それまでに入力された数の個数と合計を整数で、平均を浮動小数点数で出力するプログラム。 【プログラム】 #include <stdio.h> #include <stdlib.h> #include <string.h> #define streq(a, b) !strcmp((a), (b)) int main(int argc, char *argv[]) { int i, num, sum = 0; double avg; char buf[256]; char *endptr; for (i = 0;; i++) { printf("INPUT>"); if (fgets(buf, sizeof buf, stdin) == NULL) { perror("fgets"); exit(1); } if (streq(buf, "-9999") || streq(buf, "-9999\n")) { break; } if (streq(buf, "") || streq(buf, "\n")) { fprintf(stderr, "数値を入力してください。\n"); exit(1); } num = (int) strtol(buf, &endptr, 0); if (! (*endptr == '\n' || *endptr == '\0')) { fprintf(stderr, "数値を入力してください。\n"); exit(1); } sum += num; } printf("入力数:%d 合計:%d 平均:%g\n", i, sum, (double) sum / i); return 0; }

  • 任意のファイルを別のファイルにコピーするプログラム。

    コマンドラインからコピー元、コピー先ファイル名を指定してファイルをコピーするプログラムなんですが… #include <stdio.h> #include <stdlib.h> main(int argc, char *argv[]) { FILE *fp; if ((fp = fopen(argv[0],"r") == NULL){ printf("ファイル%sが存在しません。\n",argv[0]);exit(-1); } if ((fp = fopen(argv[1],"w") == NULL){ printf("ファイル%sがコピーできません。\n",argv[1]);exit(-1); } fclose(fp); } どこか間違っているところがあるでしょうか? ありましたら詳しく教えてもらえると幸いです。 少し自信がないのでわかる方はよろしくおねがいします。

  • プログラムエラー

    プログラムを実行したところ、こんなエラーが出てしまいました。 msgrcv failure: Argument list too long 実行したいプログラムは3つのプロセスがもつ数字を順番に並べる作業です。 1番目のプロセスはうまくいくのですが、2番目が上記のようなエラーがでてきてしまいます。 なぜでしょうか?? エラーで出てくるところは int main( int argc, char** argv ) { int qid; Qmsg message; long int myNo; int myProp; int data[NUM_DATA]; int isSwap = 0; int needMinSort = 0; int needMaxSort = 0; int got_data; int totalSwapNum = 0; int i,flag,m,n,l,s; if( argc != 2){ fprintf(stderr, "Usage: %s <own order(1-10)>\n", argv[0]); exit(1); } myNo = atol(argv[1]); if( myNo <= 0 || NUM_PROCESS < myNo ){ fprintf(stderr, "Illegal own order (%ld)\n", myNo); exit(1); } switch( myNo ){ case 1: myProp = LEFT_SIDE; printf("[%ld] is LEFT SIDE\n", myNo); break; case NUM_PROCESS: myProp = RIGHT_SIDE; printf("[%ld] is RIGHT SIDE\n", myNo); break; default: myProp = MIDDLE; printf("[%ld] is MIDDLE\n", myNo); } errno = 0; if( (qid = msgget((key_t)KEY_NO, 0666 | IPC_CREAT)) == -1 ){ perror("msgget failure"); exit(1); } message.msgData.status = MSG_AWAKE; switch( myProp ){ case LEFT_SIDE: sendMsgRhs( qid, myNo, message ); break; case MIDDLE: recvMsgLhs( qid, myNo, &message );         //ここでエラー if( message.msgData.status != MSG_AWAKE ){ exit(1); } sendMsgRhs( qid, myNo, message ); break; case RIGHT_SIDE: recvMsgLhs( qid, myNo, &message ); if( message.msgData.status != MSG_AWAKE ){ exit(1); } break; } } int recvMsgLhs( int qid, long int myNo, Qmsg* message ) { long int read_from = myNo; errno = 0; if(msgrcv(qid, message, sizeof(message->msgData), read_from, 0) == -1){ perror("msgrcv failure"); exit(1); } #ifdef SHOW_XFER_MESSAGE printf("Lhs[%2ld] ---> Recv ---> [myNo:%2ld] (%s)", message->type - 1, myNo, msgStr[message->msgData.status]); switch( message->msgData.status ){ case MSG_SWAP: case MSG_NEED: case MSG_SWAP_CNT: printf(" {data:%d}\n", message->msgData.data); break; default: printf("\n"); } #endif return errno; }