C言語 関数について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
bisuko9898

C言語 関数について

#1

投稿記事 by bisuko9898 » 7年前

関数のプロトタイプがintoddsum(int data[],int n);です。
oddsumの処理はdataないの先頭からn個のデータのうち奇数のもののみ合計し、その結果を整数で返すものです。ただしnが負の場合は結果として0を返します。

ex)
data=1 3 5 7 9
oddsum=25

このソースでどこがまちがっているか教えてもらいたいです!



#include <stdio.h>

int oddsum(int data[], int n) {
int total = data[0];
int i;



for (i = 0; i <= n; i++)
if ((data % 2) == 1) {

total += data;
return total;
}

}
#define N 5
int main(void)
{
int data[N] = { 1,3,5,7,11 };

printf("data=1,3,5,7,11\n");
printf("oddsum=%d\n", oddsum(data, N));


return 0;
}

結果
data=1 3 5 7 11
oddsum=2
となってしまいます

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: C言語 関数について

#2

投稿記事 by みけCAT » 7年前

  • コードをBBCodeのcodeタグで囲まずに貼り付けている
  • data[0]が奇数かどうかにかかわらず和に含まれ、奇数の場合は二重に足されてしまう
  • for文のループ条件が間違っているので、先頭からn個ではなくn+1個の要素について処理している
  • 計算が終わっていないのに関数からreturnしている
  • nが負の場合にreturn文が実行されず、返される値が0ではなく不定である
  • dataの出力の区切り文字がスペースではなくコンマになってしまっている
というのがまちがっていますね。
bisuko9898 さんが書きました:結果
data=1 3 5 7 11
oddsum=2
となってしまいます
そんなわけはないでしょう。(別のファイルではなく)正しい最新のソースコードを実行するようにしてください。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 13年前

Re: C言語 関数について

#3

投稿記事 by box » 7年前

配列の中に偶数も入れとかないとテストになりません。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

box
記事: 2002
登録日時: 13年前

Re: C言語 関数について

#4

投稿記事 by box » 7年前

みけCAT さんが書きました: そんなわけはないでしょう。(別のファイルではなく)正しい最新のソースコードを実行するようにしてください。
いや、今のコードではそうなるのでは?
totalをdata[0]で初期化。この時点でtotalは1。
ループに入る。
先頭要素をtotalに加算。この時点でtotalは2。
そしてreturn。
みけCAT さんが書きました: data[0]が奇数かどうかにかかわらず和に含まれ、奇数の場合は二重に足されてしまう
計算が終わっていないのに関数からreturnしている
まさに、これが起きているのでは?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

box
記事: 2002
登録日時: 13年前

Re: C言語 関数について

#5

投稿記事 by box » 7年前

bisuko9898 さんが書きました:

コード:

	int data[N] = { 1,3,5,7,11 };
	printf("data=1,3,5,7,11\n");
配列の内容が変わったら、printfの中身もそれに応じて手で変えるってことですか?
それはあまり美しい方法とはいえないですね。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: C言語 関数について

#6

投稿記事 by みけCAT » 7年前

box さんが書きました:
みけCAT さんが書きました: そんなわけはないでしょう。(別のファイルではなく)正しい最新のソースコードを実行するようにしてください。
いや、今のコードではそうなるのでは?
いや、ならないでしょう。
Ideone.comで実行すると、出力は

コード:

data=1,3,5,7,11
oddsum=2
となりました。
みけCAT さんが書きました:dataの出力の区切り文字がスペースではなくコンマになってしまっている
これが起きていますね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 13年前

Re: C言語 関数について

#7

投稿記事 by box » 7年前

ほんのちょっとした例です。

コード:

#include <stdio.h>

int oddsum(int *data, int n)
{
    int total, i;

    if (n < 0) {
        return 0;
    }
    for (total = i = 0; i < n; i++) {
        if ((data[i] % 2) == 1) {
            total += data[i];
        }
    }
    return total;
}

void print_data(int *data, int n)
{
    int i;

    for (i = 0; i < n; i++) {
        printf("%d%c", data[i], (i == n - 1) ? '\n' : ' ');
    }
}

int main(void)
{
    int data[] = { 4, 3, 1, 10, 6, 9, 8, 5, 7, 2 };
    int sz = sizeof(data) / sizeof(data[0]);

    print_data(data, sz);
    printf("oddsum=%d\n", oddsum(data, sz));
    return 0;
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。


bisuko9898

Re: C言語 関数について

#9

投稿記事 by bisuko9898 » 7年前

沢山の回答ありがとうございました。
最後に二つほどわからない点があるので質問させていただきます。
①int data[N] = { 1,3,5,7,13 };
 printf("data=1 3 5 7 13\n");
この部分を正しい方法で表示したいのと
②data=1 3 5 7 13
 oddsum=29
現時点でこの結果しか表示されないのですが
data=1 4 6 8 9 12 13
oddsum=23
という結果を加えたい場合はどのようなソースを加えればよろしいのでしょうか?

#include <stdio.h>

int oddsum(int data[], int n) {
int total;
int i;

total = 0;

if (n < 0) {
return 0;
}


for (i = 0; i <= n; i++){
if ((data % 2) == 1) {

total += data;
}
}
return total;
}
#define N 5
int main(void)
{
int data[N] = { 1,3,5,7,13 };

printf("data=1 3 5 7 13\n");
printf("oddsum=%d\n", oddsum(data, N));

return 0;
}

box
記事: 2002
登録日時: 13年前

Re: C言語 関数について

#10

投稿記事 by box » 7年前

ちょっとした例です。

コード:

#include <stdio.h>

int oddsum(int *data, int n)
{
    int total, i;

    if (n < 0) {
        return 0;
    }
    for (total = i = 0; i < n; i++) {
        if ((data[i] % 2) == 1) {
            total += data[i];
        }
    }
    return total;
}

void print_data(int *data, int n)
{
    int i;

    printf("data=");
    for (i = 0; i < n; i++) {
        printf("%d%c", data[i], (i == n - 1) ? '\n' : ' ');
    }
}

int main(void)
{
    int data[] = { 1, 3, 5, 7, 13 };
    int sz = sizeof(data) / sizeof(data[0]);
    int data1[] = { 1, 4, 6, 8, 9, 12, 13 };
    int sz1 = sizeof(data1) / sizeof(data1[0]);

    print_data(data, sz);
    printf("oddsum=%d\n", oddsum(data, sz));
    print_data(data1, sz1);
    printf("oddsum=%d\n", oddsum(data1, sz1));
    return 0;
}
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

box
記事: 2002
登録日時: 13年前

Re: C言語 関数について

#11

投稿記事 by box » 7年前

Ruby教への入信のお誘いのため、同じ動きをするであろうコードをRubyで書いてみた。

コード:

def oddsum(d, n)
  return 0 if n < 0
  total = 0
  n.times { |i| total += d[i] if d[i] % 2 == 1 }
  total
end

def print_data(d, n)
  print "data="
  n.times { |i| printf "%d%s", d[i], (i == n - 1) ? "\n" : " " }
end

def solve(d, n)
  print_data(d, n)
  printf "oddsum=%d\n", oddsum(d, n)
end

foo = [ 1, 3, 5, 7, 13 ]
bar = [ 1, 4, 6, 8, 9, 12, 13 ]
solve(foo, foo.size)
solve(bar, bar.size)
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

box
記事: 2002
登録日時: 13年前

Re: C言語 関数について

#12

投稿記事 by box » 7年前

みけCAT さんが書きました:
box さんが書きました: いや、ならないでしょう。

コード:

data=1,3,5,7,11
oddsum=2
当方がそうなるといったのは、oddsumの結果が2になることを指しているのであって、dataの出力が
カンマ区切りであることは特に気にしていません(ていうか、カンマ区切りであろうがスペース区切りであろうがどうでもいいと思ってた)でした。

当該のコードではoddsumが2という正しくない答えになる、ということはご理解いただけますか?そっちの方が当該のコードにおける
本質的な問題だと思っています。カンマ区切りかどうかは些末な話。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

閉鎖

“C言語何でも質問掲示板” へ戻る