11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

私がC言語を習い始めの頃に勘違いした引数渡し

Last updated at Posted at 2020-12-30

他の記事に触発されて記事を書きました。

C言語を習い始めた1990年頃のこと・・・
以下ような例題がありました。(当時こんな書き方はできなかったはずですが・・・)

C言語
#include <stdio.h>

void sub(char c)
{
    printf("%c\n", c);
}

int main(void)
{
    char message[] = "Hello, world!";
    sub(message[0]);
}

ちょっと改造しようと思い、講師に変な質問をしてしまいました:
sub関数に "Hello, world!"H を渡したのですから、隣の e も簡単に取り出して表示できますよね?」と。
引数cの文字'H'"Hello, world!"'H' なのだから、sub関数で (&c)[1] とすれば隣の文字 'e' を取り出せるんじゃないかと思ってしまったのです。
「なんでできないの?」としばらく思っていました。

変数の値をコピーして引数に渡す(値渡しする) C言語 では無理

実際には、"Hello, world!" の 文字'H' のデータをコピーして sub関数の引数cに代入されているので、変数cの文字'H'から元の"Hello, world!"'H'の位置を特定することはできません。

このような処理を行いたい場合、呼び出し元からデータの位置(アドレス)を渡せばできます。

C言語
#include <stdio.h>

void sub(char *c)  // *でデータ位置を指し示す(ポイントする)引数になる
{
    printf("%c\n", c[0]);  // [0] で先頭文字 'H'
    printf("%c\n", c[1]);  // [1] で隣の文字 'e'
}

int main(void)
{
    char message[] = "Hello, world!";
    sub(&message[0]);  // &でデータ位置(アドレス)を渡す
}

変数領域への参照を引数に渡せる(参照渡しできる) C++言語 なら可能

ちなみに、変数領域への参照を引数に渡せる C++ 言語であれば、私が最初に思ったことを実現できます。

C++言語
#include <stdio.h>

void sub(char &c)  // &で呼び出し元の変数に別名を付けて呼び出し元の変数領域を使う
{
    printf("%c\n", c);        // 変数cは普通のchar型変数として扱える
    printf("%c\n", (&c)[1]);  // 変数cのアドレスは呼出し元変数のアドレスなので次の文字を取り出せる
}

int main(void)
{
    char message[] = "Hello, world!";
    sub(message[0]);
}
実行結果
H
e

さいごに

講師の方々、いろいろ間違った理解をする受講生がいますので、温かいサポートをお願いします。(自戒も含めて)

11
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?