出産前後の痔にはご注意!

三つの整数の変数a,b,cを用意して、プログラムの各変数に任意の値を代入する
例:a=9,b=31,c=25 このプログラムを実行して
「a=9,b=31,c=25です.よって b>c>a です.」
と表示するプログラムを組みなさい

とゆう課題が出されたのですが
switch文を使ってプログラムを組んで課題は終わったのですが・・・

switch文以外方法でこのプログラムが組めるのか
プログラムの例を教えてください。

あとプログラムを組むときにはシンプルで行数の少ないプログラムのほうがいいのですか?

教えてくださいお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (10件)

単純な if ですが、こんなのもありかと。


2つの条件を && でつなぐくらいまでだと、案外追いかけやすいですね。

if ((a > b) && (a > c))// a が最大
{
if (b > c) {// a > b > c}
else { // a > c > b)
}
else if ((b > a) && (b > c))
{
if (c > a) {// b > c > a}
else { // b > a > c)
}
else if ((c > a) && (c > b))
{
if (a > b) {// c > a > b}
else { // c > b > a)
}
else
{
// 等しいものが一組以上ある
}
    • good
    • 0

( a, b, c がすべて異なるとして)



>switch文以外方法でこのプログラムが組めるのか

「ソート」の思考で作ってみました(*1)。
発展(数の増加)させることが可能です。

ただ冒頭の

>三つの整数の変数a,b,cを用意して、プログラムの各変数に任意の値を代入する

には反しています、結果重視ということで・・。

なお、今回は、「三つの整数」の6通りなので「switch文」を用いた方がシンプルと思います(*2)。
#7 さんの「こるなら」バージョンをヒントに、こらずにそのまんま・・。

>シンプルで行数の少ないプログラムのほうがいいのですか?

「虫」にしてみれば、住みにくい環境と思います。

注:共にインデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
*1 ++++++++++++++++++++++++++++++++++++++
#include <stdio.h>

#define KOSU 3

typedef struct{
 int iRank;
 int iVal;
 char cName;
}KADAI;

KADAI sWork[ KOSU ] = {
 { 0, 9, 'a' },
 { 0, 31, 'b' },
 { 0, 25, 'c' }
};

int main()
{
 int i, j, k, iMax, iJun, iCnt = 0;

 printf( "a=%d,b=%d,c=%dです.よって ", sWork[ 0 ].iVal, sWork[ 1 ].iVal, sWork[ 2 ].iVal );

 for( i = 0; i < KOSU; i++ ){

  for( j = 0; j < KOSU; j++ ){ // 最大抽出

   if( sWork[ j ].iRank ) continue;

   iMax = sWork[ j ].iVal;
   iJun = j;

   for( k = ( j + 1 ); k < KOSU; k++ ){

    if( sWork[ k ].iRank ) continue;
    if( sWork[ k ].iVal < iMax ) continue;

    iMax = sWork[ k ].iVal;
    iJun = k;
   }
   iCnt++;

   sWork[ iJun ].iRank = 9; // 済み

   printf( "%c", sWork[ iJun ].cName );

   if( KOSU != iCnt ) printf( ">" );
  }
 }
 printf( " です.\n" );

 return( 1 );
}
*2 ++++++++++++++++++++++++++++++++++++++
#include <stdio.h>

int main()
{
 int a = 9, b = 31, c = 25;

 printf( "a=%d,b=%d,c=%dです.よって ", a, b, c );

 switch( ( a < b ) * 4 + ( b < c ) * 2 + ( c < a ) * 1 ){

  case 6: printf( "c>b>a" );
    break;
  case 5: printf( "b>a>c" );
    break;
  case 4: printf( "b>c>a" );
    break;
  case 3: printf( "a>c>b" );
    break;
  case 2: printf( "c>a>b" );
    break;
  case 1: printf( "a>b>c" );
    break;

  default: printf( "?????" );
 }
 printf( " です.\n" );

 return( 1 );
}
    • good
    • 0

No.6 です。


確かにできていますね、switch で。

前者は、実はおぼろげには考えましが。が、この方針でできるかどうか確信が持てる前に挫折しました。
後者は……同質の判断が3つネストすると思考が止まるので、やっぱり、「私には」無理です。

でも、これがプログラムできたのなら、どちらにしても、ちょっとすごいなと。
    • good
    • 0

こるなら


switch ((a<b)*4 + (b<c)*2 + (c<a)*1)
馬鹿なら
switch (a<b) なんかのネスト
でできます>#6.
    • good
    • 0

ふと思ったのですが、switch による制御で本当にできますか?


「課題」として、どのようなソースができあがったのか、非常に興味があります。

私にはできませんでした。
    • good
    • 0

条件判断が分散すると、何をやっているのか一目でわからなくなります。


では、どういうのがシンプルかと言えば、ひとつの尺度として、以前は、
「そのコードを電話越しに言って、相手にロジックがわかるか?」というのがありまいた。

そういうことからすると、条件判断を読み替えたり、ひとつずつ片付けたりというのも
意味がある方法です。

以下のコードは、「a, b, c がすべて異なる」場合にしかうまく動きませんが。

int max;
char max_name;

int min;
char min_name;

int middle;
char middle_name;

// 最大値を探す
max = a;
max_name = 'a';

if (max < b)
{
max = b;
max_name = 'b';
}

if (max < c)
{
max = c;
max_name = 'c';
}


// 最小値を探す
min = a;
min_name = 'a';

if (min > b)
{
min = b;
min_name = 'b';
}

if (min > c)
{
min = c;
min_name = 'c';
}


// 中間値を探す(それは、最大でも最小でもないもの)
if ((max != a) && (min != a))
{
middle = a;
middle_name = 'a';
}

if ((max != b) && (min != b))
{
middle = b;
middle_mame = 'b';
}

if ((max != c) && (min != c))
{
middle = c;
middle_name = 'c';
}
    • good
    • 0

短くしようとするあまりに凝ったコードを書いてしまうよりは、多少冗長でもロジックが見やすいコードの方が基本的に好まれます。


とりあえず同値は考えずに作ると、ifで普通に書けばこんな感じでしょう。

printf("a = %d, b = %d, c = %dです. よって ");
if(a < b)
{
 if(c < a)
 {
  printf("c < a < b");
 }else{
if(b < c)
  {
   printf("a < b < c");
  }else{
   prinff("a < c < b");
  }
}
}else{
 if(c < b)
 {
  printf("c < b < a");
 }else{
  if(a < c)
  {
   printf("b < a < c");
  }else{
   printf("b < c < a");
  }
 }
}
printf("です。\n");
    • good
    • 0

#include <stdio.h>



typedef struct {
char name; /* 名前 */
int value; /* 値 */
} var;

void swap(var* x, var* y) {
var t = *x;
*x = *y;
*y = t;
}

int main() {
/* 名前と値の組をみっつ用意 */
var x, y, z;

/* テキトーに代入 */
x.name = 'a';
y.name = 'b';
z.name = 'c';

x.value = 9;
y.value = 31;
z.value = 25;

/* 名前と値を列挙 */
printf("%c=%d, %c=%d, %c=%d です ", x.name, x.value, y.name, y.value, z.name, z.value);

/* 大きい順に並び替え */
if ( x.value < y.value ) swap(&x,&y);
if ( y.value < z.value ) swap(&y,&z);
if ( x.value < y.value ) swap(&x,&y);

/* 大きい順に名前だけ列挙 */
printf("よって %c > %c > %c です\n", x.name, y.name, z.name);
return 0;
}
    • good
    • 0

この仕様が与えられたときに「switch で組む」というのが理解できん. 普通は if だろ.


b>c>a なら「b>c>a」と表示するとか, そんなことだよな?
    • good
    • 0

if文や?でもできます。


if文の例
char *最大;
char *中間;
char *最小;
if ( a > b ) {
  if ( a > c ) {
    最大 = "a";
    if ( b > c ) {
      中間 = "b";
      最小 = "c";
    }
    else {
      中間 = "c";
      最小 = "a";
    }
  }
  else {
    最大 = "c";
    中間 = "a":
    最小 = "b";
  }
}
以下略
?の例
char *最大 = ( a > b ? ( a > c ? "a" : "c") : ( b > c ? "b" : "c"));
char *中間 = ( a > b ? ( b > c ? "b" : ( a > c ? "c" : "a" )) : ・・・略
char *最小 = ・・・略;

>あとプログラムを組むときにはシンプルで行数の少ない
「シンプル」をどう考えるかですが、最も重要なことは
「分かり易い」ことです。if文と?はどうでしたか?
あと、日本語の識別名が許されるVS2010やVBでは
私は日本語識別名を使うように心がけています。
英語やローマ字読みのアルファベットを使うよりずっと
分かり易いでしょ?
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Qchar型にint型の数値を代入する。

たとえば、
int num;
char box; 

numに何らかの整数値が入っているときに、そのnumの中に入っている値をchar型に文字列として代入したいときはどのようにすればいいのでしょうか?

Aベストアンサー

sprintf()っていう関数がありますよ。書式は

sprintf(char型の配列の先頭ポインタ,フォーマット,変数...)

二番目の引数以降はprintf()の引数と同じです。たとえば

int num;
char box[256];
num=100;
sprintf(box,"%d",num);
printf("%s",box);

→100と出力される

Q引数 戻り値 return文について

今、C言語を初めて勉強してます。

勉強していて、引数と戻り値、return文

についてよくわかりません。

どなたか詳しく素人にもわかるように教えて

頂けないでしょうか?よろしくお願いします。

Aベストアンサー

まず、関数とは何らかの処理をして結果を返してくれるものです。わざとらしい例ですが二つの数を足してその結果を返す関数を見てみましょう。

#include <stdio.h>

int add( int hoge, int piyo ){
return hoge + piyo;
}

int main(void){
int data;

data = add( 253, 434 );
printf( "%d", data );

return 0;
}

見てわかると思いますが、引数とは関数内の処理に使うデータです。
このデータは関数を呼び出すときに与えます。

add( 253, 434 )

すると与えられたデータは関数に渡され仮引数と言うものに格納されます。
この例では hoge に 253、piyo に 434 が格納されます。

int add( int hoge, int piyo ){

この仮引数は普通の変数のように使うことが可能なのです。

hoge + piyo

そしてこの結果を戻り値として return 文で返してやります。

return hoge + piyo;

返すとは具体的にどこへ返すのかと言うと呼び出したところへです。
ここでは main 関数内の呼び出し元です。

data = add( 253, 434 );

data と言う変数へは関数によって返された戻り値(関数値とか返却値とかとも言ったりします)が格納されます。つまり 253 と 434 を足した数です。

引数も戻り値も結局はデータです。処理させたいデータが引数で、処理した結果であるデータが戻り値です。

return は呼び出し元へ結果を返すためのものです。


C言語の関数にはいろいろな種類があります。

引数も戻り値もあるもの。

int add( int hoge, int piyo ){
return hoge + piyo;
}

引数はあるが戻り値のないもの。

void add( int hoge, int piyo ){
printf( "%d", hoge + piyo );
}

戻り値はあるが引数のないもの。

#include <stdlib.h>
#include <time.h>

int getRandNum(void){
srand( time( NULL ) );
return rand() % 500;
}

戻り値も引数もないもの。

void print(void){
printf( "%d + %d = %d", 253, 434, 253 + 434 );
}

これらの使い分けはデータの内容や型、処理の内容により適宜必要なものを使ってください。

まず、関数とは何らかの処理をして結果を返してくれるものです。わざとらしい例ですが二つの数を足してその結果を返す関数を見てみましょう。

#include <stdio.h>

int add( int hoge, int piyo ){
return hoge + piyo;
}

int main(void){
int data;

data = add( 253, 434 );
printf( "%d", data );

return 0;
}

見てわかると思いますが、引数とは関数内の処理に使うデータです。
このデータは関数を呼び出すときに与えます。

add( 253, 434 )

すると与...続きを読む

Qコンパイルエラー invalid operands to binary

自己啓発で入力文字列をBASE64デコードする関数を作っているのですが、L20~L23(a[0] = strchr(b64, p[0]) - b64;)でコンパイルエラーinvalid operands to binaryが発生して色々試行錯誤しているのですが、どうしてもエラーがとれません。
ソースをここに書くのは大変恐縮なのですが、原因がわかる方がいらっしゃいましたら、教えていただけないでしょうか?

char *Base64n(unsigned char *buf, size_t length, size_t *outlen)
{
const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst         uvwxyz0123456789+/=";
unsigned char *p;
unsigned char *q;
unsigned char a[4];
char *RtnBuf;
int j=0;
int cnt;

RtnBuf = (char *)malloc(length+1);
memset(RtnBuf, 0, length+1);

p = (unsigned char*)buf;
q = (unsigned char*)RtnBuf;
cnt = 0;
while(*p != 0) {
a[0] = a[1] = a[2] = a[3] = 0;
a[0] = strchr(b64, p[0]) - b64;
a[1] = strchr(b64, p[1]) - b64;
a[2] = strchr(b64, p[2]) - b64;
a[3] = strchr(b64, p[3]) - b64;

q[0] = ((a[0] << 2) | (a[1] >> 4)) & 0xff;
cnt++;

if (p[2] != '=') {
q[1] = ((a[1] << 4) | (a[2] >> 2)) &0xff;
cnt++;
}
if (p[3] != '=') {
q[2] = ((a[2] << 6) | a[3]) & 0xff;
cnt++;
}
p += 4;
q += 3;
}
*outlen = cnt;
return(RtnBuf);
}

コンパイルはRed Hatでgccを使ってコンパイルしています。
引数は第1引数がデコード対象の文字列、第2引数がデコード対象文字列長、第3引数がデコード後の文字列長で、戻り値がデコード後の文字列です。

自己啓発で入力文字列をBASE64デコードする関数を作っているのですが、L20~L23(a[0] = strchr(b64, p[0]) - b64;)でコンパイルエラーinvalid operands to binaryが発生して色々試行錯誤しているのですが、どうしてもエラーがとれません。
ソースをここに書くのは大変恐縮なのですが、原因がわかる方がいらっしゃいましたら、教えていただけないでしょうか?

char *Base64n(unsigned char *buf, size_t length, size_t *outlen)
{
const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrst ...続きを読む

Aベストアンサー

手元にgccが無いので、Windowsのbcc32でコンパイルしてみたところ、
エラーが出ずに通ってしまいました。
だから自信がないのですが…。

a[0] = strchr(b64, p[0]) - b64;



a[0] = strchr(b64, p[0]) - b64[0];

に変えてみたらどうでしょう。
"invalid operands to binary"
は、たぶん、マイナスの両側で型が違っていることを
表しているのではないでしょうか。(←これも自信なし)
strchr()が返すのはchar *型ですが、
b64の型は、charの配列型です。
型が違うので、コンパイラが不正と判断したのかもしれません。

とするとbcc32でなぜ通ったかが問題になるのですが…。
C言語規格でも、ポインタ同士の引き算のところは
ややこしくなっています。
規格解釈の違いがあるのかもしれません。

Q戻り値の意味がわかりません…

戻り値とはどういう値なのか簡単な例文で教えて頂けますか?

Aベストアンサー

バカくさいかもしれませんが簡単な例えをだしてみます。
2人の子供がいて、名前をそれぞれ太郎・花子にしましょう。この2人の子にある役割を決めます。
・花子は飴をもらうと、それをチョコにする役割。(できるかは別として)
・太郎は花子を呼んで飴をあげる役割。

さてこの例では太郎の飴が引数(ひきすう)になり
花子のチョコが戻り値になります。

このイメージを元に次の文を読んでみてください。

「プログラム中の関数やサブルーチンが処理を終了し
呼び出し元に処理の結果として返す値。」

これが戻り値の正しい定義です。
そのほかにはNo1さんのような役割指すときも、それを「戻り値」と呼んだりします。

Qfgetsで拾われる改行文字を削除したい

お世話になります

 C言語初心者のものです。今課題でC言語を用いたプログラミングを
Fedora上でやっています。問題は、fgetsでテキストファイルから、取得
した文字列の中から改行文字を削除できないことです。文字変数のアド
レスはわかっているのですが、終端文字に置換しようとすると、セグメ
ントエラーになってしまいます。これは如何にして解決すべきでしょう
か。よろしくお願いします。

Aベストアンサー

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが最大文字数に達したり、ファイルの最後になったりで、strに改行文字が含まれない場合には、このループは止まりません(Segmentension Falutになって止まる)

・そのような状態になってないか、予めチェックする
・ループを終了させる仕組みを用意しておく
: forの終了条件を記述する、for中で if(*(str+i)=='\0') { break;} 等としておく、等
といった対策が必要です。


あと細かいところを言えば
・strを配列で用意したなら *(s+i)じゃなくてs[i]でいいんじゃないかな
・あるいは char *pみたいにしておいて、 iのループでなく pでループを組む( for(p=str;*p!='\0';p++) )とか。

ポインタとかアドレスとか、C言語の用語としてあるものを別の意味に使うとまぎらわしいです。

「ポインタ」「アドレス」と言われたら、 この例なら str, str+i が思い浮びます。
「文字変数のアドレス」だと
char c ;
に対しての
&c
が思い浮びます。

配列なら「添字」、意味的には「x文字目」ですね。

> for(i=0;;i++){
> if(*(str+i)=='/n') {
> *(str+i)='\0';
> break;
> }
> }
/nが\nの間違いなら、この方法で半分正解です。もう少し広い範囲(可能なら全体)で見ないことにはなんとも言えません。
fgetsが...続きを読む


人気Q&Aランキング