質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.47%

  • C

    3834questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

C言語で引数が何に使われているのかわからない部分があります

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 960

ababab

score 51

C言語で、関数「reverse」の「num」がいつどこに使われているのかわかりません。

void reverse(int[], int);

int main(int argc, const char * argv[]) {
    int data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int i;
    
    reverse(data, 10); 
    for (i = 0; i < 10; i++) {
        printf("%d ", data[i]);
    }
    printf("\n");
    return 0;
}

void reverse(int array[], int num) {
    int i, tmp;
    for(i = 0; i < num / 2; i++) {
        tmp = array[i];
        array[i] = array[num - 1 - i];
        array[num - 1 - i] = tmp;
    }
}

この場合、「void reverse(int array[], int num)」において、この関数内で使われているarray[]の値をmain内のdataに使っていますよね。
ですが「num」の値は、main内のどこで使われているのでしょうか...

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

+3

numは配列のサイズを指定しているだけですので、mainでは使用していません。

また、配列はポインターを関数に渡しているので内容を書き換えることができますが、intは値をコピーして渡しているだけですので、読み取り専用になります。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/01/12 23:15

    回答ありがとうございます。
    つまり、関数の引数に配列を使う場合、「(int array[],」の次は配列の要素数を表すint型の変数を書かなければならないということでしょうか?

    キャンセル

  • 2015/01/12 23:21

    C言語では、配列のサイズをarrayから知ることができませんので、それを渡す必要があります。
    順番は後でなくてもかまいません。例えば、main関数では、配列のサイズargcが先に来ていますね。

    キャンセル

+1

例えば、
int sum(int, int);

int main(){
  printf("%d\n",sum(10,20));
}

int sum(int x, int y){
  return x+y;
}
というプログラムがあったときに、sumの中のxymainのどこで使われているのか疑問に持ちますか?持たないとすれば、質問文の、
ですが「num」の値は、main内のどこで使われているのでしょうか...
というのが的外れだとわかると思います。

また、
この場合、「void reverse(int array[], int num)」において、この関数内で使われているarray[]の値をmain内のdataに使っていますよね。 
も、やや表現がおかしく、正しく書き直すと、
この場合、「void reverse(int array[], int num)」において、main関数内のdataを、この関数内でarray[]という名前で参照していますよね。
です。
さらに書くと、
この場合、「void reverse(int array[], int num)」において、main関数内の10を、この関数内でnumという名前で参照していますよね。
というのが、numについての説明となります。


蛇足ですが、他の方の指摘のように、main関数中ででてくる配列サイズを数字を直接書くのは良くない。
普通は、
int main(int argc, const char * argv[]) {
    int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int i;

    reverse(data, sizeof data/sizeof data[0]);
    for (i = 0; i < sizeof data/sizeof data[0]; i++) {
        printf("%d ", data[i]);
    }
    printf("\n");
    return 0;
}
のように、sizeof演算子を使うと思います。これはコンパイル時に計算されるので、10と書いたのと実行コードは同じになります。プログラムのどこにも配列サイズを書く必要が無い。
煩雑な書き方だと思えば、
#define array_size(var) (sizeof var/sizeof var[0])
のように、マクロを定義してarray_size(data)と使うことも出来ます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

checkベストアンサー

0

c言語において、配列の要素数を配列変数から取得することはできないのでそのような仕様になるのだと思います。
例として

 int data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
という配列変数があるとして、変数dataが要素数10の配列だと証明するもの変数dataにはありません。

void reverse(int array[], int num) { 
    int i, tmp; 
    for(i = 0; i < num / 2; i++) { 
        tmp = array[i]; 
        array[i] = array[num - 1 - i]; 
        array[num - 1 - i] = tmp; 
    } 
} 
上記reverse関数では、第一引数のint array[]の要素の並びを入れ替える処理を行いますが、そのためにはarray[]の要素数がわからないといけません。
しかしarray[]からは要素数を取得できないので引数を追加して要素数を指定するような仕様になります。
また、reverse関数に指定する第二引数が実際の要素数と違う場合には配列として確保したメモリ以外の部分を参照してしまうので、想定しない動きをします。(配列の要素ではない値を取得したり、プログラムが落ちるなど)

>>int array[]の次に出てきたものは配列の要素数になると言う解釈でよろしいでしょうか?
上記の解釈ではなく、reverse関数においては、第一引数int array[]の次、第二引数のint numには要素数が指定されることを前提にしているということです。
第二引数のint numに指定される値が間違いなくint array[]の要素数であるというのはreverse関数の使用者が保障しなくてはいけません。

以上です。 
参考になれば幸いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

お邪魔します。

int main(int argc, const char * argv[]) {
*   int data[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int i;
    
*   reverse(data, 10); 
*   for (i = 0; i < 10; i++) {
        printf("%d ", data[i]);
    }
    printf("\n");
    return 0;
} 
上記でアスタリスク(*)をつけた行で、10という数値が配列dataの要素数として使用されていますね。
本来これはマジックナンバーなので、定数として宣言すべきで
int main(int argc, const char * argv[]) {
    const int DATA_LENGTH = 10;
    int data[DATA_LENGTH] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int i;
    
    reverse(data, DATA_LENGTH); 
    for (i = 0; i < DATA_LENGTH; i++) {
        printf("%d ", data[i]);
    }
    printf("\n");
    return 0;
} 

void reverse(int array[], int num) {
    int i, tmp;
    for(i = 0; i < num / 2; i++) {
        tmp = array[i];
        array[i] = array[num - 1 - i];
        array[num - 1 - i] = tmp;
    }
} 
のようにするのがよい慣習とされています。
reverse関数を呼び出すとき、二つ目の引数にDATA_LENGTH(=10)を渡しているので、reverse関数内部ではnumが10になります。(他の回答者さんの回答が正確で、10をコピーして渡しています)
このようにすれば、少しはわかりやすくなったのではないでしょうか?

以上です。
参考になれば幸いです。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/01/12 23:11

    回答ありがとうございます。
    void reverse..のint array[]の次に出てきたものは配列の要素数になると言う解釈でよろしいでしょうか?
    仮に関数reverse内で他にint型の変数を使う場合、
    (int array[], int num2, int num)とした場合は、arrayの要素数はnum2になるということでよろしいでしょうか?
    初歩的な質問で申し訳有りません

    キャンセル

  • 2015/01/12 23:23

    その様にreverse関数の引数を宣言して内部の実装を変更しなければ、numが配列の要素数として使用されます。(reverse関数内部ではnumという名前を配列の要素数として使用しているからです)
    なので、渡す側もreverse(data, ???, DATA_LENGTH)というように渡さなければいけません。
    また、num2を配列の要素数として渡すよう変更するのであれば、reverse関数の中身のnumとなっている部分をすべて、num2に変更した上で、新たに追加した引数numを使用するコードを追加します。

    ①引数に渡す側が記述している順番で、関数には値(やポインタ)が渡される。
    ②関数内のコードでは、引数として宣言している名前で値(やポインタ)を受け取り使用することができる。
    ということになります。

    キャンセル

関連した質問

  • 解決済

    1からNまでの二乗和を求める

    1からNまでの二乗和を求めるプログラムを作れ、という課題をやっているのですが、完成したと思いコンパイルし実行してみると、=0 という答えが返ってきました。 コンパイルした時、警

  • 解決済

    java 乱数 配列

            }     } なるべく短いプログラムにしたいです。よろしくお願いします。

  • 解決済

    皆様のお答えを聞かせてください。打ちこんだ整数を逆に並べて出力する

    このコードはマイナスの値を打つと、アラームが鳴り整数値を打つように 指示します。そして整数値が打ちこまれると、それを10で割り余りを出す、10で割るという繰り返しで引っくり返した数

  • 受付中

    点数別分布グラフ

    点数分布のグラフですが、少し長いように感じました。もう少し短くすることはできますか? またこのコードに対して何かご意見がありましたらお願いします。 #inc

  • 解決済

    【C言語】スタックをリストで実現するプログラム

    毎度お世話になっております。 高橋麻奈さんの「やさしいC アルゴリズム」をみて勉強しているのですが、リストを使ったスタックのコードで、がコンパイルエラーになってしまいました。 コ

  • 解決済

    linux 処理時間の表示

    C言語でLinuxを使っています。メモリを確保したりするプログラムなのですが、以下のプログラムを修正して 、5秒間で何回の入れ替えを行えるかを計測できるようにしてもらいたいです。初

  • 解決済

    エラーメッセージの意味が分からない

    発生している問題・エラーメッセージ 文字列配列を辞書順にソートしてから表示するプログラムです。エラーメッセージは恐らく、無効な引数(型がint) のような内容が書いてあると思うの

  • 受付中

    入力した数値の最大値、2番目に大きい数値、3番目に大きい数値

    10個の整数を入力して、1番大きい数値、2番目に大きい数値、3番目に大きい数値を表示したいのですがうまくいきません。 3番目の数値が0になってしまいます。 改善の仕方を教えていただ

同じタグがついた質問を見る

  • C

    3834questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。