akayoroshi の回答履歴

全164件中1~20件表示
  • C言語について

    以下の問題の入力データをどうやって入力すれば、実行結果のようになるのでしょうか?教えていただけると助かります。添付画像です。

  • ほぼ同じプログラムで結果が違う問題

    プログラムAとBが以下のようになっています。 プログラムA ------------- do n=1,100000 write(*,*) n コード 300行ぐらい enddo プログラムB -------------- do n=1,100000 if(mod(n,100).eq.1) write(*,*) n 同じソースコード enddo 両者の違いはループカウンタの画面表示頻度です。Aは毎回、Bは100回に1回印刷します。それだけですね。 ところが、プログラムAは淡々と走っていきますが、BはNaNなどを生じてしまい結果が違います。このような問題の原因は何でしょうか。出力頻度なので内容とは関係ないはずだと思うのですが。 実はコンパイラを変えたらBの問題が消えました。NaNの出力がなくなり大体想定した値が出てきています。2つのコンパイラはともにgfortranですが、何か仕様が違うということがあるでしょうか。 プログラムとしてはせいぜい10万点ぐらいの2次元配列を何度も繰り返し計算するということで、今のPCの演算速度では大したことはありません。 大昔、パソコンFortranは計算の規模(配列の規模と反復計算の回数など)に応じてコンパイラオプションを付けたり、コンパイラ自体が別物であったりしていました。そういう問題があるのかなと思うのですが。もし、何か心当たりがありましたらよろしくお願いします。

  • 乱数の順位付けのアルゴリズム

    [0,1]の範囲で乱数を1000個、配列に発生させて、小さいもの100個を選び出すアルゴリズムということを考えます(知りたいのは数値と配列番号、むしろ配列番号が大事)。まず想定できるのはソートですが、それにもいろんなものがあり、クイックソート、バブルソートなどが挙げられます。ソートのアルゴリズムは既に開発されつくしたのかもしれませんが、どのようになっているでしょうか。一番高速な(かつ間違いない)な方法が1つあればそれを採用したいのですが。 そして1つ厄介なのですが、そのトップ100個以外の900個はソートする必要がないということです。私が考えているアルゴリズムは、 1.既に100個の選ばれていると仮定(初期はすべて1) 2.新しい1個が来たとき、100個の最低値よりも小さいなら考慮の対象なのだから最低値を交換してその100個でソートする。そうでない場合は何もしない。 3.次の新しい1個を調べて、項目2をする。 4.発生させた1000個でそれを繰り返す。 このアルゴリズムだと100個のソートを何百回かぐらいやることになります。 これをするぐらいだったら1000個のソートを1回やればいいということになるでしょうか(不必要な残りの900個もソートされてしまう)。あるいはその1回の1000個のソートの中でやる必要のない処理を排除する工夫があるかもしれません。 問題が難しくなく、素人っぽくコード化できると思いますが、その分、非効率なところも放置されそうなので高速化できるコードの書き方があったら教えて頂きたいのですが。コードというよりアイディアだけ説明していただいても助かります。実際はフォートランになると思いますが。よろしくお願いします。

  • 簡単な遠隔操作用のソフト

    遠隔操作をしたことのない私が簡単に自宅にあるパソコンを、持ち出したモバイルパソコン(レッツノート)で遠隔操作しようと思ったら、どのソフトがまず簡単にできるでしょうか?

  • 夫の行動、どう思われますか?

    結婚して一年目になります。 私は初婚、夫は再婚で、前の家庭に娘さん(6歳)がおり、月に1~2度夫が娘さんと二人で面会しています。 (家はお互い自転車で行ける距離にあります。娘さんの記憶にはないようですが、赤ちゃんの頃に一度だけ会ったことがあります。) 今日起きた出来事なのですが、夫の行動に疑問を感じモヤモヤしています。 今日夫は娘さんと会う予定で朝から外出、私も朝から出かける予定だったのですが、体調があまりすぐれず、お昼頃まで寝ていました。 そろそろ出掛けなきゃと着替え始めた頃、玄関の鍵が空く音がして、あれ?と思ったと 同時に娘さんの声も聞こえてきて、リビングに入ってきたのがわかりました。 夫は私が寝室に居ることに気づいていない様子。 私も出かけるリミットが迫っていた&すっぴん、パジャマのまま急に出ていくのが微妙で、悩んだ末に寝室から夫に電話しました。 寝室に居るんだけど…と伝えたら、夫は驚いた様子で、気を遣ってしばらくして家を出ていきました。 家に来た理由としては、近くの釣り堀で魚を釣ったから焼いて一緒に食べようと思ったんだ、とのこと。 このようなことは前にもありました。 リビングに色々なキャラクターのぬいぐるみがあるのですが、「娘がこれ可愛いっていってたよ!」と急に言われたことがあり、私の不在時に家に上げていたことがわかりました。 夫としては忘れ物をとりに立ち寄り、娘がリビングをみたいといったので見せた、という流れのようですが…。 部屋が散らかっていたこともあり、「家散らかってたのに恥ずかしいよ」と伝えたのですが、「子供だし気にしないよ!」と言われ夫は気にしない様子。 その時は、自分も心が狭いかな…と強くは夫に言いませんでした。 元々の話に戻りますが、これらの夫の行動は果たして普通なのでしょうか。 私としては、いくら義理の娘になったとはいえ、娘さんとは会ったことがないに等しいので、今の時点では家族とも知り合いとも思えません。(決して娘さんが嫌なわけではなく、どうしても厳しい言い方になってしまいますが、それが本心です) 夫と私の中で娘さんの立場付けが違う為のすれ違いだと思っていますが、これをわかってもらえるにはどうしたら良いでしょうか。 娘さんに会えば私も少し気持ちが変わってくるかと思うのですが、そこも考えてしまう点です。 果たして娘さんは私に会いたいのか?前の奥さんはどう思うのか?等々。 夫としては、娘さんに会って欲しいようです。前に突然、今から連れていくから!と一方的な連絡が来たことがありました。前の奥さんや娘さんの了承とったの?と聞いたらまだとのことで、結果として、前の奥さんとしては娘さんがそうしたいなら良い、娘さん自身も会ってみたいとのことで会う流れになったのですが、娘さんが直前にやっぱり恥ずかしい、とのことでその日に会うことはありませんでした。 夫は家族に対して、家族がどういう気持ちかを深く考えていない気がします。 私が家が散らかっているから恥ずかしい、という点をあげても「子供も自分も気にしないから」と終わらせてしまうし、お互いに断りもなく突然会わせようとすることも、なに考えてるんだろうというのが正直な気持ちです。 前の奥さんだって、本心では私に会わせたくないかもしれないし、娘さんだって、本当は会いたくないけどパパが言うから断りづらいという気持ちかもしれません。 段階を踏むのが苦手な人なので、連れてきちゃえばこっちのもの!的な考えでの行動だと思います。 私としては、なにも考えずに行動したと前の奥さんに思われたくないし、娘さんだって私はただの子供ではなく、ひとりの女性として扱うべきとと思うので、夫との考えの差に混乱しています。 どう伝えたら角がたたないでしょうか。 長文でわかりづらく申し訳ありません。 どなたかアドバイスを頂けたら嬉しいです。

    • ベストアンサー
    • noname#232718
    • 夫婦・家族
    • 回答数3
  • 等比数列についてです。

    1+2+3+・・・・・・+(n-1)の答えが1/2n(n-1)にと書いてあったのですが、どうしてそうなるのかわかりません。教えてください。 等差数列の和の公式1/2n{2a+(n-1)d}で解こうとしたのですがうまく行きません。なぜできないかも教えていただけると嬉しいです。 よろしくお願いします。

  • C言語 fopen

    初心者の質問になります。現在ファイルがオープンできるかどうかを確認したいのですが、指定したディレクトリの中のファイルを指定しているのですが、オープンできませんという結果が返ってきます。同じ場所にファイルを置いてファイル名だけでしていするとオープンが出来ます。 何卒よろしくおねがいします。 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> int main(void) { FILE *fp; char *filename = "/file/d20151001.csv"; fp = fopen(filename,"r"); if (fp == NULL) { printf("\aファイルをオープンできません\n"); } else { printf("ファイルがオープンできました\n"); fclose(fp); } return (0); } ディレクトリ(わかりにくくてすいません汗) file------d20151001.csv data.c 環境 VisualStudio

  • C言語 スタックを使ったプログラミングについて

    C言語のスタックを使った逆ポーランド記法を使ったプログラミングについて質問です。 今回作ったプログラムは、キーボードで入力した逆ポーランド記法の数式を計算してその結果を出力するといったものです。 実際に以下のプログラムをcygwin上で動かしてみたのですが、コアダンプ表示が出てうまく動作しませんでした。 一応printfなどを使って確認してみたところ。main関数までは辿り着いているみたいなのですが、スタックを使うあたりから怪しくなっているみたいでよくわかりませんでした。。 どこが間違っているのかわかりやすく教えていただけると大変助かります。 長々とすみません、よろしくお願いいたします。 #include <stdio.h> #include <ctype.h> #include <stdlib.h> typedef struct cell_{ double vall; struct cell_ *next; }cell; cell *sp = NULL; int empty(void){ cell *retnode = sp -> next; if(retnode == NULL){ return 1; } return 0; } void push(double x){ cell *newnode; newnode = (cell*)malloc(sizeof(cell)); newnode -> vall = x; newnode -> next = sp -> next; sp -> next = newnode; } double pop(void){ int i; double num; i = empty(); if(i == 1) exit(1); cell *shownode = sp -> next; num = shownode -> vall; sp -> next = shownode -> next; free(shownode); return num; } double print(void){ cell *printnode = sp -> next; return printnode -> vall; } int main(){ double a, b; double i; char c; char *ends; while((c = getchar()) != EOF){ if(isdigit(c)){ a = c; push(a); }else{ switch(c){ case '+': a = pop(); b = pop(); i = a + b; push(i); break; case '-': a = pop(); b = pop(); i = a - b; push(i); break; case '*': a = pop(); b = pop(); i = a * b; push(i); break; case '/': a = pop(); b = pop(); i = a / b; push(i); break; case EOF || '\n': a = print(); printf("%f\n", a); default: printf("Irregular character is found. Try again\n"); while((c = getchar()) != EOF && c != '\n'){} break; } } } return 0; }

  • クイックソートをC++で作りたいのですが・・・

    題の通り、C++でクイックソートを作りたいのですが、以下のコードではセグメンテーションエラーで動きませんでした。partition関数があやしいと思い、色々と試してみたのですが、やはりできなかったので、質問させていただくことにしました。 結果としては、print関数で昇順に表示出来ればいいのですが・・・。 以下のコードのどこをどう変えれば良いのか、ご指摘の方、何卒よろしくお願い致します。 #include <iostream> #include <vector> using namespace std; class Array { private: vector<int> array; public: void insert( int value ){ array.push_back( value ); } int getSize( ){ return (int)array.size( ); } void quick_sort( ){ quick_sort( 0, (int)array.size( ) - 1 ); } void quick_sort( int left, int right ); int partition( int left, int right ); void swap(int *a,int *b){int tmp=*a;*a=*b;*b=tmp;} void print( ); }; // クイックソートにより配列の添字 left ~ right の部分を整列する関数 void Array::quick_sort( int left, int right ) { if ( left >= right ) { return; } int v = partition( left, right ); quick_sort( left, v - 1 ); quick_sort( v + 1, right ); } //この関数を考える // 配列の添字 left ~ right の部分を,pivot の値より小さい要素と,大きい要素に分割し pivot の位置を返す関数 int Array::partition( int left, int right ) { int i=left; //左からの処理位置 int j=right; //右からの処理位置 int pivot=array[(int)(left+right)/2]; //基準 int tmp=0; while(true){ while(array[i]<pivot){i++;} while(array[j]>pivot){j--;} if(i>=j){return i;} tmp=array[i]; array[i]=array[j]; array[j]=tmp; i++; j++; } } // 配列の内容を表示する関数 void Array::print( ) { for ( int i = 0; i < (int)array.size( ); i++ ) { cout << array[i] << " "; } cout << endl; } int main( ) { Array a1; a1.insert( 56 ); a1.insert( 34 ); a1.insert( 57 ); a1.insert( 64 ); a1.insert( 3 ); a1.insert( 87 ); a1.insert( 85 ); a1.insert( 37 ); a1.insert( 21 ); a1.insert( 4 ); a1.insert( 68 ); a1.insert( 62 ); a1.insert( 42 ); a1.insert( 55 ); a1.insert( 63 ); a1.insert( 95 ); a1.insert( 7 ); a1.insert( 32 ); a1.insert( 78 ); a1.insert( 11 ); cout << "要素数: " << a1.getSize( ) << endl; cout << "ソート前: "; a1.print( ); a1.quick_sort( ); // ここで,ソートを行う関数を呼び出す cout << "ソート後: "; a1.print( ); return 0; }

    • ベストアンサー
    • noname#225287
    • C・C++・C#
    • 回答数1
  • 多態性を利用して派生クラスの関数を呼びたい

    環境はVS2013,言語はC++です. 基底クラス側で,基底クラスのポインタを引数に受ける仮想関数を宣言し, 派生クラスでその実装をします. 派生クラス側で引数に派生クラスのポインタを受けて,派生クラスのメンバにアクセスできるようにしたいのです. 作成したサンプルを下記に示します. Hello()は関係ありません. また,これはあくまで簡略化したサンプルなだけなので,thisポインタからメンバにアクセスすればよいというものではありません. #include <iostream> class Base { public: int i; Base() :i(0) {} virtual void print(Base *p) { std::cerr << "Base : " << i << std::endl; } virtual void hello() = 0; }; class Super : public Base { public: int x; Super() : x(1) {} void print(Super *p) { std::cerr << "Super : " << p->x << std::endl; } void hello() { std::cerr << "hello" << std::endl; } }; int main(void) { Base *p; p = new Super; p->print(p); } 上記を実行した結果,Base::print()が呼び出されました. print関数の引数に派生クラスSuperの実態を差すBase型ポインタを与えたときに,Super::print()を呼び出せるようにするには,何か方法はありますか. p->print(p)の呼び出し部分をp->((Super*)p)にキャストしても結果は同じくBase::print()が呼ばれました. Base::print()の実装を無くした場合は,未解決の外部参照のコンパイルエラーが発生し, Base::print()を純粋仮想関数にした場合は,Super側でSuper::pirnt(Base*p)を実装しなければならないのか,抽象クラスのインスタンス化ができないというコンパイルエラーが発生します. これは,派生クラスとはいえ,引数リストの型が違うのでオーバーライドされていないということですよね. 引数をBase *p,Super *pからそれぞれvoid *pへ変更し,Super::print()内で(Super *)へキャストしなおしたところ,きちんとオーバーライドされ,うまくはいきました. しかしながら,この方法だと派生クラス側で実装する際に毎回キャスト処理を書かなくてはなりません. 他に何かきれいな方法はないでしょうか.

  • 多態性を利用して派生クラスの関数を呼びたい

    環境はVS2013,言語はC++です. 基底クラス側で,基底クラスのポインタを引数に受ける仮想関数を宣言し, 派生クラスでその実装をします. 派生クラス側で引数に派生クラスのポインタを受けて,派生クラスのメンバにアクセスできるようにしたいのです. 作成したサンプルを下記に示します. Hello()は関係ありません. また,これはあくまで簡略化したサンプルなだけなので,thisポインタからメンバにアクセスすればよいというものではありません. #include <iostream> class Base { public: int i; Base() :i(0) {} virtual void print(Base *p) { std::cerr << "Base : " << i << std::endl; } virtual void hello() = 0; }; class Super : public Base { public: int x; Super() : x(1) {} void print(Super *p) { std::cerr << "Super : " << p->x << std::endl; } void hello() { std::cerr << "hello" << std::endl; } }; int main(void) { Base *p; p = new Super; p->print(p); } 上記を実行した結果,Base::print()が呼び出されました. print関数の引数に派生クラスSuperの実態を差すBase型ポインタを与えたときに,Super::print()を呼び出せるようにするには,何か方法はありますか. p->print(p)の呼び出し部分をp->((Super*)p)にキャストしても結果は同じくBase::print()が呼ばれました. Base::print()の実装を無くした場合は,未解決の外部参照のコンパイルエラーが発生し, Base::print()を純粋仮想関数にした場合は,Super側でSuper::pirnt(Base*p)を実装しなければならないのか,抽象クラスのインスタンス化ができないというコンパイルエラーが発生します. これは,派生クラスとはいえ,引数リストの型が違うのでオーバーライドされていないということですよね. 引数をBase *p,Super *pからそれぞれvoid *pへ変更し,Super::print()内で(Super *)へキャストしなおしたところ,きちんとオーバーライドされ,うまくはいきました. しかしながら,この方法だと派生クラス側で実装する際に毎回キャスト処理を書かなくてはなりません. 他に何かきれいな方法はないでしょうか.

  • バブルソート、あなたはどちら派?

    昇順にソートする場合ですが、 配列の先頭とその次の値を比較し、大きい数字の方を後ろへ持っていくパターンと 配列の最後とその手前を比較し、小さい数字を前へ持っていくパターンがあると思います。 前者のほうが、湖底から水面へ泡がだんだん大きくなっていくバブルのイメージで 長年これがスタンダードだと思っていたのですが、 後者についてを「小さい泡がだんだん移動していくイメージなのでバブルソートと言う」と 断言しているサイトや書籍もあります。 どちらも間違いではないと思います。 ですが、他人に教えることを想像したとき、 どちらかというと先に前者を教えてから、後者のやり方もあるよと伝えた方が 直感的に理解しやすいかなと思いました。 皆さんはどちら派ですか? また、前者と後者を使い分けるメリットがもしもあればご教示頂けませんか?

  • C言語 クイックソートについて

    クイックソートでわからない点があるため、 質問させていただきます。 ----------------------------------------------------- ~省略~ data = [5, 3, 4, 2, 6, 1]; no = 6; //データの個数 ~省略~ dqsort(data, 0, no-1); ~省略~ void dqsort(double data[], int lower, int upper) {   int i, boundary; //boundaryは配列の前半と後半の境界を示す   if(lower >= upper) { return; }   //基準値となる値(データの中央に位置する値)とデータの先頭の値を入れ替える   swapdata(&data[lower], &data[(lower + upper)/2]);   boundary = lower; //boundaryを先頭に移動させる     for(i=lower+1; i<=upper; i++) {       if(data[i] < data[lower]) {         //配列の前半部分に移動し、境界を移動する         swapdata(&data[++boundary], &data[i]);       }     }   //最後に基準値を境界位置にコピー   swapdata(&data[lower], &data[boundary]);   //配列の前半部分をクイックソート   dqsort(data, lower, boundary-1);   //配列の後半部分をクイックソート   dqsort(data, boundary+1, upper); } void swapdata(double *i, double *j) {   int temp;   temp = *i;   *i = *j;   *j = temp; } --------------------------------------------------------- 基準値と配列の先頭のデータを入れ替えた後、 データは、[4, 3, 5, 2, 6, 1]となり、lower = 0であるため、 data[boundary]はdata[0]となります。 for文の最初のループでdata[0]<data[1]なら、 swapdata(&data[++boundary], &data[i]); となっているのですが、 [++boundary]の部分はboundary=0に1を足してから処理するため、 swapdata(&data[1], &data[1]); となると思うのですが、そうすると同じデータを入れ替えることになってしまいます。 何が間違っているのか、教えていただけますでしょうか。

  • C言語 クイックソートについて

    クイックソートでわからない点があるため、 質問させていただきます。 ----------------------------------------------------- ~省略~ data = [5, 3, 4, 2, 6, 1]; no = 6; //データの個数 ~省略~ dqsort(data, 0, no-1); ~省略~ void dqsort(double data[], int lower, int upper) {   int i, boundary; //boundaryは配列の前半と後半の境界を示す   if(lower >= upper) { return; }   //基準値となる値(データの中央に位置する値)とデータの先頭の値を入れ替える   swapdata(&data[lower], &data[(lower + upper)/2]);   boundary = lower; //boundaryを先頭に移動させる     for(i=lower+1; i<=upper; i++) {       if(data[i] < data[lower]) {         //配列の前半部分に移動し、境界を移動する         swapdata(&data[++boundary], &data[i]);       }     }   //最後に基準値を境界位置にコピー   swapdata(&data[lower], &data[boundary]);   //配列の前半部分をクイックソート   dqsort(data, lower, boundary-1);   //配列の後半部分をクイックソート   dqsort(data, boundary+1, upper); } void swapdata(double *i, double *j) {   int temp;   temp = *i;   *i = *j;   *j = temp; } --------------------------------------------------------- 基準値と配列の先頭のデータを入れ替えた後、 データは、[4, 3, 5, 2, 6, 1]となり、lower = 0であるため、 data[boundary]はdata[0]となります。 for文の最初のループでdata[0]<data[1]なら、 swapdata(&data[++boundary], &data[i]); となっているのですが、 [++boundary]の部分はboundary=0に1を足してから処理するため、 swapdata(&data[1], &data[1]); となると思うのですが、そうすると同じデータを入れ替えることになってしまいます。 何が間違っているのか、教えていただけますでしょうか。

  • C言語 クイックソートについて

    クイックソートでわからない点があるため、 質問させていただきます。 ----------------------------------------------------- ~省略~ data = [5, 3, 4, 2, 6, 1]; no = 6; //データの個数 ~省略~ dqsort(data, 0, no-1); ~省略~ void dqsort(double data[], int lower, int upper) {   int i, boundary; //boundaryは配列の前半と後半の境界を示す   if(lower >= upper) { return; }   //基準値となる値(データの中央に位置する値)とデータの先頭の値を入れ替える   swapdata(&data[lower], &data[(lower + upper)/2]);   boundary = lower; //boundaryを先頭に移動させる     for(i=lower+1; i<=upper; i++) {       if(data[i] < data[lower]) {         //配列の前半部分に移動し、境界を移動する         swapdata(&data[++boundary], &data[i]);       }     }   //最後に基準値を境界位置にコピー   swapdata(&data[lower], &data[boundary]);   //配列の前半部分をクイックソート   dqsort(data, lower, boundary-1);   //配列の後半部分をクイックソート   dqsort(data, boundary+1, upper); } void swapdata(double *i, double *j) {   int temp;   temp = *i;   *i = *j;   *j = temp; } --------------------------------------------------------- 基準値と配列の先頭のデータを入れ替えた後、 データは、[4, 3, 5, 2, 6, 1]となり、lower = 0であるため、 data[boundary]はdata[0]となります。 for文の最初のループでdata[0]<data[1]なら、 swapdata(&data[++boundary], &data[i]); となっているのですが、 [++boundary]の部分はboundary=0に1を足してから処理するため、 swapdata(&data[1], &data[1]); となると思うのですが、そうすると同じデータを入れ替えることになってしまいます。 何が間違っているのか、教えていただけますでしょうか。

  • C言語 sscanf関数で変換に失敗した場合

    sscanf関数で変換に失敗した場合という点がよくわからなかったため、 質問させていただきます。 入力された整数の2乗を返すプログラム --------------------------------------------------- # include <stdio.h> # define BUFSIZE 256 int main(void) {   int input;   char linebuf[BUFSIZE];   printf("整数を入力してください。\n");   while(fgets(linebuf, BUFSIZE, stdin) != NULL) {     if(sscanf(linebuf, "%d", &input) != 0) {       printf("%dの2乗は%dです。\n", input, input*input);       break;     }     else {       printf("整数を入力してください。\n");     }   }   return 0; } ----------------------------------------------------- 例えば、入力された値が文字列であった場合、 if(sscanf(linebuf, "%d", &input) != 0) の文のところで"%d"と整数を指定しているため、 変数inputに入力された値を格納できません。 sscanf関数は変換エラーの場合は「EOF」を返すとなっているにもかかわらず、 ここでは「0」以外の場合(!= 0)となっています。 変換エラーというのは、入力された値とsscanf関数で指定した書式が異なる場合は含まないのでしょうか。 そうであるならば、変換エラーというのはどのようなものなのでしょうか。 ちなみに、「!= 0」の部分を「!= EOF」にして実行したところ、 無関係な数値が出力されました。 (aを入力したら、4198555の2乗は~と出力されました)

  • C言語 sscanf関数で変換に失敗した場合

    sscanf関数で変換に失敗した場合という点がよくわからなかったため、 質問させていただきます。 入力された整数の2乗を返すプログラム --------------------------------------------------- # include <stdio.h> # define BUFSIZE 256 int main(void) {   int input;   char linebuf[BUFSIZE];   printf("整数を入力してください。\n");   while(fgets(linebuf, BUFSIZE, stdin) != NULL) {     if(sscanf(linebuf, "%d", &input) != 0) {       printf("%dの2乗は%dです。\n", input, input*input);       break;     }     else {       printf("整数を入力してください。\n");     }   }   return 0; } ----------------------------------------------------- 例えば、入力された値が文字列であった場合、 if(sscanf(linebuf, "%d", &input) != 0) の文のところで"%d"と整数を指定しているため、 変数inputに入力された値を格納できません。 sscanf関数は変換エラーの場合は「EOF」を返すとなっているにもかかわらず、 ここでは「0」以外の場合(!= 0)となっています。 変換エラーというのは、入力された値とsscanf関数で指定した書式が異なる場合は含まないのでしょうか。 そうであるならば、変換エラーというのはどのようなものなのでしょうか。 ちなみに、「!= 0」の部分を「!= EOF」にして実行したところ、 無関係な数値が出力されました。 (aを入力したら、4198555の2乗は~と出力されました)

  • 2次元配列とポインタの引数受け渡しについて

    2次元配列を関数に渡すときは、引数に渡す2次元配列と同じサイズを指定、もしくは2次元目のサイズのみ合わせて渡す方法がありますが、両方とも違うサイズで同じ関数を使いたいです。 最初は中身が同じで引数で受け取る2次元配列のサイズだけ、それぞれに合わせた引数を持つ関数を2つ作っていたのですが、なんだか冗長な気がしました。 そこで、2次元配列の先頭ポインタとサイズを受け取るようにすればいいのかと思い、テストとして次のプログラムを作成してみました。 #include <stdio.h> void func(unsigned char *a, int y, int x); int main(void) { unsigned char a[10][10]; func(a, 10, 10); printf("%d\n", a[7][4]); return 0; } void func(unsigned char *a, int y, int x) { int i, j; for (i = 0; i < y; i++) { for (j = 0; j < x; j++) { *(a + i*y + j) = i * j; } } } もちろんこれでも動くのですが、やはりこういう書き方はルールにはないので、コンパイルで警告が出ます。 a.c: In function ‘main’: a.c:10: warning: passing argument 1 of ‘func’ from incompatible pointer type a.c:4: note: expected ‘unsigned char *’ but argument is of type ‘unsigned char (*)[10]’ このような書き方はやはりやめたいいのでしょうか。 また、その際はサイズ別に関数を作るしかないのでしょうか。 他にいい方法があれば教えていただけると助かります。

  • 変な質問なんですが!?

    #include <stdio.h> int main() { int kosuu[3]; int goukei; scanf("%d", &kosuu[0]); scanf("%d", &kosuu[1]); scanf("%d", &kosuu[2]); goukei = kosuu[0] + kosuu[1] + kosuu[2]; printf("GOUKEI %d\n", goukei); return 0; }  以上で20、30、40の順に入力します。   それで  結果が  20  30  40 GOUKEI 90 の結果が出ると思います。   そこで 結果が  20 30 40 GOUKEI 90 にすることは可能でしょうか!?  以上よろしくお願いします。

  • 「配列変数」て何ですか!?

    #include <stdio.h> #include <string.h> int main() { int suuretsu[10]; int *p; for ( p = suuretsu; *p != 0; p++ ){ printf("p=%p *p=%d\n", p, *p); } }  以上のプログラムで!  「配列変数」が”どこ”に当たるのか  ?いまいちピンとこないです!。  参考書にも「配列変数」の解説がありません!  ググッたら・違ったプログラムでの解説はあり、  なんとなく分かりはしました。   しかし!プログラムが変わるとニュアンスの違いで!  また違った関係があるみたいでいまいち分かりません--    ここでいう、「配列変数」はどこに当たりますか!?  宜しくお願いします。