戻し値がchar
戻し値がchar
C言語を学んでまだ2ヶ月なので色々と知識に乏しいのですが、よろしくお願いします。
#include<stdio.h>
char change(int number);
int main()
{
int x;
char y[10][10];
x=56;
y=change(x);
return 0;
}
char change(int number)
{
char result[10][10];
sprintf(result[1],"%d",number);
return result;
}
xにintの56を入れたらyに文字列の56を返す関数を使ったプログラムにしたいのですが、コンパイルするとエラーが出てしまいます。何処が悪いのでしょうか?
#include<stdio.h>
char change(int number);
int main()
{
int x;
char y[10][10];
x=56;
y=change(x);
return 0;
}
char change(int number)
{
char result[10][10];
sprintf(result[1],"%d",number);
return result;
}
xにintの56を入れたらyに文字列の56を返す関数を使ったプログラムにしたいのですが、コンパイルするとエラーが出てしまいます。何処が悪いのでしょうか?
Re:戻し値がchar
バグさん返信有難う御座います。しかし本当にすいませんが、ポインタとやらがよくわかりません;;大変お手数ですが、少々変えてもらってもかまわないので、実際に何処を直せばいいか書いてもらえませんか?それを見てポインタを理解したいと思います。できればでいいので、よろしくお願いします。
Re:戻し値がchar
とてもありがたいです!よろしくお願いします。文字列は自信がないんですが、文字は'abc'とかを扱う型でprintfで出力する時に%cを使って、文字列は後ろに[/url]をつけて複数保存できるようにした型で%sを使うんですよね?
Re:戻し値がchar
基本的に文字とは、あくまで1文字('A'←こんなのです)を指し、2文字以上("ABCDE"←こんなのです)になると文字列になります。
ちなみに、'abc'という記述をするとエラーになります。'(シングルクォーテーション)で括ってよいのは文字だけです。複数の文字…文字列を記述したい場合は、"(ダブルクォーテーション)で括ってやりましょう。
通常、文字列を扱う場合、char型の配列を利用するのですが、char型に限らず、配列については御存じでしょうか?
ちなみに、'abc'という記述をするとエラーになります。'(シングルクォーテーション)で括ってよいのは文字だけです。複数の文字…文字列を記述したい場合は、"(ダブルクォーテーション)で括ってやりましょう。
通常、文字列を扱う場合、char型の配列を利用するのですが、char型に限らず、配列については御存じでしょうか?
Re:戻し値がchar
それでは、1つ問題です。
char str[6] = {"ABCDE"};
上記のように初期化した場合、a[0],a[1],a[2],a[3],a[4],a[5]のそれぞれに格納されている値は何でしょうか?
char str[6] = {"ABCDE"};
上記のように初期化した場合、a[0],a[1],a[2],a[3],a[4],a[5]のそれぞれに格納されている値は何でしょうか?
Re:戻し値がchar
>>>> ちなみに、'abc'という記述をするとエラーになります。'(シングルクォーテーション)で括ってよいのは文字だけです。
とりあえず,'abc'は「実装依存の振る舞い」なので,エラーになるとは限りません。
> a[0]=A,a[1]=B,a[2]=C,a[3]=D,a[4]=E,a[5]=なし
値を示す場合はソースの表記にあわせる方がよいです。
1と書かれたら,数値の1か数字の'1'か区別がつきません。
「なし」という値はあり得ません (空ポインタはあるが,これは値がなしであるわけではない)。
a[0] : 'A'
a[1] : 'B'
a[2] : 'C'
a[3] : 'D'
a[4] : 'E'
までは正解です。あとは,a[5]の値が何になっているか,です。
とりあえず,'abc'は「実装依存の振る舞い」なので,エラーになるとは限りません。
> a[0]=A,a[1]=B,a[2]=C,a[3]=D,a[4]=E,a[5]=なし
値を示す場合はソースの表記にあわせる方がよいです。
1と書かれたら,数値の1か数字の'1'か区別がつきません。
「なし」という値はあり得ません (空ポインタはあるが,これは値がなしであるわけではない)。
a[0] : 'A'
a[1] : 'B'
a[2] : 'C'
a[3] : 'D'
a[4] : 'E'
までは正解です。あとは,a[5]の値が何になっているか,です。
Re:戻し値がchar
a[5]は'\0'が入りますが、ほかはOKです。
こちらが想定していたよりも、分かっているようですね(^-^)
それでは…
理由は分かりますか?
こちらが想定していたよりも、分かっているようですね(^-^)
それでは…
void main(void) { char a[6]; sprintf(a, "%s", "ABCDE"); }こうした場合と…
void Dainyu(char* str) { sprintf(str, "%s", "ABCDE"); } void main(void) { char a[6]; Dainyu(a); }こうした場合、両方ともa[/url]の中は同じ物になります。
理由は分かりますか?
Re:戻し値がchar
YuOさんもご教授有難う御座います。確かに’’が必要ですね。
えと、問題の方は上の方がそのままmain内で実行されていて、下の方はDainyuという関数を自分で作って、それをmainで使用しているから結局は結果が同じになるんですよね?
えと、問題の方は上の方がそのままmain内で実行されていて、下の方はDainyuという関数を自分で作って、それをmainで使用しているから結局は結果が同じになるんですよね?
Re:戻し値がchar
いや、たしかにそうなのですが…
main関数の中のa[/url]が、何故Dainyu関数の中で書き替えられたか?の理由です。
void Test(int c)
{
int d = 1234;
c = d;
}
void main(void)
{
int a = 0;
Test(a);
}
こんなプログラムを実行しても、aの中身は0のままで変わりませんよね?この理由も分かりますか?
main関数の中のa[/url]が、何故Dainyu関数の中で書き替えられたか?の理由です。
void Test(int c)
{
int d = 1234;
c = d;
}
void main(void)
{
int a = 0;
Test(a);
}
こんなプログラムを実行しても、aの中身は0のままで変わりませんよね?この理由も分かりますか?
Re:戻し値がchar
え~と、Test(a);だけだったら戻し値が入る場所が指定されてないからですか?
となると、先ほどのプログラムでa[/url]が書き換えられた理由が分かりません;;
となると、先ほどのプログラムでa[/url]が書き換えられた理由が分かりません;;
Re:戻し値がchar
>>え~と、Test(a);だけだったら戻し値が入る場所が指定されてないからですか?
そうですね、そういう考え方も正しいですが、今はポインタの勉強をしているので、戻り値の事は、今だけはとりあえず忘れてください(^-^)
>>となると、先ほどのプログラムでa[/url]が書き換えられた理由が分かりません;;
という事で、ここからがようやく本題です。
『何故、値を書き換えられたのか?』ですが、これは変数の中身ではなく、変数が収められている場所(アドレス)を渡しているからなんです。
ちょっと、脱線しますが、たとえ話です。
1冊の本を思い浮かべてください…。あなたの読みたい場所を探すにはどうしますか?
おそらく目次を見るのではないかと思います。それでは、目次には何が書かれているでしょうか?
そう、ページ数ですね。アドレスというのは、ここでいうページ数だと思って下さい。
そして、ポインタというのは、そのページ数を指し示す『しおり』のようなものだと思って下さい。
文字列が書き換わった理由は、文字列の収められた場所を関数の引数として渡してやり、そのページを書き換えたので、内容が書き換わった訳です。
そして、1つ前の書き込みで、値が書き換わらなかったのは、本の中身をコピーして、コピーした紙を書き換えていたから、本そのものの内容は変わらなかったという訳なんです。
サンプルです
そうですね、そういう考え方も正しいですが、今はポインタの勉強をしているので、戻り値の事は、今だけはとりあえず忘れてください(^-^)
>>となると、先ほどのプログラムでa[/url]が書き換えられた理由が分かりません;;
という事で、ここからがようやく本題です。
『何故、値を書き換えられたのか?』ですが、これは変数の中身ではなく、変数が収められている場所(アドレス)を渡しているからなんです。
ちょっと、脱線しますが、たとえ話です。
1冊の本を思い浮かべてください…。あなたの読みたい場所を探すにはどうしますか?
おそらく目次を見るのではないかと思います。それでは、目次には何が書かれているでしょうか?
そう、ページ数ですね。アドレスというのは、ここでいうページ数だと思って下さい。
そして、ポインタというのは、そのページ数を指し示す『しおり』のようなものだと思って下さい。
文字列が書き換わった理由は、文字列の収められた場所を関数の引数として渡してやり、そのページを書き換えたので、内容が書き換わった訳です。
そして、1つ前の書き込みで、値が書き換わらなかったのは、本の中身をコピーして、コピーした紙を書き換えていたから、本そのものの内容は変わらなかったという訳なんです。
サンプルです
#include <stdio.h> void Change(int nNumber, char szBuf[10][10]); int main() { int x; char y[10][10]; x = 56; // 第2引数のyはy[10][10]の先頭のアドレスを示します Change(x, y); // Change関数の中身で書き換えられたのはy[1][/url]の中身なので、y[1]を表示する printf("%s\n", y[1]); return 0; } void Change(int nNumber, char szBuf[10][10]) { sprintf(szBuf[1], "%d", nNumber); }
Re:戻し値がchar
#include<stdio.h>
char change(int number,char buf[1][10]);
int main()
{
int x;
char y[1][10];
x=56;
change(x,y);
printf("%s\n%s\n",y[0],y[1]);
return 0;
}
char change(int number,char buf[1][10])
{
sprintf(buf[0],"%d",number);
sprintf(buf[1],"%d",number-11);
}
今このように作り変えてみたら
56
45
とちゃんと表示されました!階乗を計算するpow(x, y)と同じような使い方なんですね。
でも授業では
y【returnの返し値を入れる】=change(x【実因数】);
と習っていて、今までこのように使っていたのですが、何故返し値が文字列になったとたん
change(x,y);
という書き方にしなければならないのですか??
言ってしまえばy=pow(x);でもいいような気になってしまうのですが・・・。
char change(int number,char buf[1][10]);
int main()
{
int x;
char y[1][10];
x=56;
change(x,y);
printf("%s\n%s\n",y[0],y[1]);
return 0;
}
char change(int number,char buf[1][10])
{
sprintf(buf[0],"%d",number);
sprintf(buf[1],"%d",number-11);
}
今このように作り変えてみたら
56
45
とちゃんと表示されました!階乗を計算するpow(x, y)と同じような使い方なんですね。
でも授業では
y【returnの返し値を入れる】=change(x【実因数】);
と習っていて、今までこのように使っていたのですが、何故返し値が文字列になったとたん
change(x,y);
という書き方にしなければならないのですか??
言ってしまえばy=pow(x);でもいいような気になってしまうのですが・・・。
Re:戻し値がchar
それは、変数には寿命が存在するからです。
基本的にスコープ(環境によって例外はありますが、{ }で括られている範囲)内で用意された変数は、そのスコープ内でのみ有効となり、スコープの外に出た時点で破棄されてしまう物だと思って下さい。
一番最初にさっかんさんが書かれたプログラムですと、change関数内で用意された配列のアドレスを戻り値としていましたよね?
これをしてしまうと、change関数を出た時点で、アドレスを受け取ったものの、実体が存在しないという事になってしまい、危険なんですね。
基本的にスコープ(環境によって例外はありますが、{ }で括られている範囲)内で用意された変数は、そのスコープ内でのみ有効となり、スコープの外に出た時点で破棄されてしまう物だと思って下さい。
一番最初にさっかんさんが書かれたプログラムですと、change関数内で用意された配列のアドレスを戻り値としていましたよね?
これをしてしまうと、change関数を出た時点で、アドレスを受け取ったものの、実体が存在しないという事になってしまい、危険なんですね。
Re:戻し値がchar
うまくいったのは偶然の産物であるようです。
というのは、
> char y[1][10];
この定義だと
> printf("%s\n%s\n",y[0],y[1]);
y[1]は定義範囲外だからです。buf[/url]についても同じことが言えます。
というのは、
> char y[1][10];
この定義だと
> printf("%s\n%s\n",y[0],y[1]);
y[1]は定義範囲外だからです。buf[/url]についても同じことが言えます。
Re:戻し値がchar
>定義範囲外とはどういうことですか?
簡単に言うと"配列の外側"です。
char ch[3];
と配列を確保すると、
ch[0]からch[2]までの3つのcharの領域として定義されます。
このときch[100]の位置は、定義された配列の範囲の外側であるということです。
簡単に言うと"配列の外側"です。
char ch[3];
と配列を確保すると、
ch[0]からch[2]までの3つのcharの領域として定義されます。
このときch[100]の位置は、定義された配列の範囲の外側であるということです。
Re:戻し値がchar
バグさんを初め、YuOさん、BOXさん、組木紙織さん本当に有難う御座いました。
あと一つ疑問があるのですが、スレ違いなので改めて投稿させていただきます。
初めに書いた通り、今年大学生になって初めてプログラミングの世界に触れた初心者なので、本当に基本的なことすら分かりませんが、よろしければまたご教授の程よろしくお願いします!
あと一つ疑問があるのですが、スレ違いなので改めて投稿させていただきます。
初めに書いた通り、今年大学生になって初めてプログラミングの世界に触れた初心者なので、本当に基本的なことすら分かりませんが、よろしければまたご教授の程よろしくお願いします!