ページ 11

またまた文字列

Posted: 2009年2月18日(水) 15:09
by 馬鹿太郎
このプログラムは、数字の並びである文字列stを整数値に変換した値を返す関数です。
たとえば、stが"1234"であれば整数値1234を返します。ただし、文字列中に数字以外の
文字が一つでも入っていれば-1を返します。

・文字列stにはchar型の文字列が格納されているのですよね?char型のサイズは1バイトですから、
 たとえば文字列stが"1k2u"だったら、たとえば1000番地に'1'1001番地に'k'1002番地に'2'1003番地に'u'
 とそれぞれ格納されるわけですよね?
 この認識が間違っていたら、教えてください。

・no = no * 10 + st - '0'
 がわかりません。


int strtoint(const char st[/url])
{
int i, no = 0;

for (i = 0; str; i++) {
if (st >= '0' && st <= '9') {
no = no * 10 + st - '0';
}
else {
return(-1);
}
}
return(0);
}

Re:またまた文字列

Posted: 2009年2月18日(水) 15:32
by non
文字の'0'はJISコードで0x30(10進数の48)です。
同様に'1'は0x31です。
アスキーコード表(またはJISコード表)をググってみてください。
ですから、
st-'0'を計算したら、0~9の数値になりますよね。
桁数が数桁有るので、10倍してその桁を足します。

Re:またまた文字列

Posted: 2009年2月18日(水) 15:35
by 通りすがり
コードはタグで囲みましょう。

Re:またまた文字列

Posted: 2009年2月18日(水) 15:43
by non
>文字列stにはchar型の文字列が格納されているのですよね?char型のサイズは1バイトですから、
>たとえば文字列stが"1k2u"だったら、たとえば1000番地に'1'1001番地に'k'1002番地に'2'1003番地に'u'
>とそれぞれ格納されるわけですよね?

確認するプログラムです。試してください。
#include<stdio.h>
int main(void)
{
	char str[/url]="ABC123";
	int i=0;
	while(str){
		printf("str[%d]:address=%p moji=%c code=%d\n",i,&str,str,str);
		i++;
	}
	return 0;
}

Re:またまた文字列

Posted: 2009年2月18日(水) 15:44
by abc
数字の並びである文字列stを整数値に変換した値を返す関数です

返してるのは0、-1だけですよ??
しかも文字列stを整数値に変換してないですねー、

文字の数値チェックはあってると思いますよ。

Cコンパイラがあるならメモリマップみてくださいちなみに"1k2u"だったら
{012FF74 31 6B 32 75 00 00 00 00 00 00 CC CC C0 FF 12 1k2u......フフタ..}になります

012FF74があなたの言ってる1000番地にあたります。(アドレス)

質問の答えになればいいのですが,,,,

Re:またまた文字列

Posted: 2009年2月18日(水) 16:02
by non
> 返してるのは0、-1だけですよ??

ただ単なる入力ミスでしょう。
return(no) です。
途中でstrってのもあるし・・・

> しかも文字列stを整数値に変換してないですねー、

してますよ。noに。返してないだけで。

Re:またまた文字列

Posted: 2009年2月18日(水) 16:09
by 馬鹿太郎
すいませんっ!

no = no * 10 + st - '0'

ここ、詳しくお願いします。

Re:またまた文字列

Posted: 2009年2月18日(水) 16:13
by non
普通に10進数で考えたとき、
1234は
((1×10+2)×10+3)+4
であることを理解してください。

Re:またまた文字列

Posted: 2009年2月18日(水) 16:14
by non
式にミスあり
((1×10+2)×10+3)×10+4

Re:またまた文字列

Posted: 2009年2月18日(水) 16:31
by 馬鹿太郎
文字列stを整数値に変換した値を返すとはどういう意味ですか?

no = no * 10 + st - '0'

やっぱりわかりません・・・

Re:またまた文字列

Posted: 2009年2月18日(水) 17:02
by Kou
馬鹿太郎様

> no = no * 10 + st - '0'
>
> やっぱりわかりません・・・

仮にstに文字列"1234"が入っているとします。

まずは式中の「st-'0'」を「st-48」で考えてみてください。(48→'0'の10進でのASCIIコード)

その上で、式がfor文でループしているので、'0'→48、'1'→49で考えると処理が追えると思いますよ。

Re:またまた文字列

Posted: 2009年2月18日(水) 19:56
by toyo
文字'0'と数値0が別のものであるのはわかってますか。
文字'0'は数値48です

数値 12 は 1 * 10 + 2 はわかりますよね
noが1でst - '0' が2にあてはまります

Re:またまた文字列

Posted: 2009年2月18日(水) 20:37
by 馬鹿太郎
>数値 12 は 1 * 10 + 2 はわかりますよね
>noが1でst - '0' が2にあてはまります

でも、ここのnoは0では?

うーーん・・・

Re:またまた文字列

Posted: 2009年2月18日(水) 20:52
by 御津凪
> でも、ここのnoは0では?

計算の結果は no に代入されるので、
ループした次の計算では0ではなくなります。
(最初に '0' が来たら、その時だけ 0 が代入されますが)

たとえば、 "123" の文字列が入力された時、計算順序は
no =  0 * 10 + 1; → no に   1 が代入される
no =  1 * 10 + 2; → no に  12 が代入される
no = 12 * 10 + 3; → no に 123 が代入される
と、なります。

Re:またまた文字列

Posted: 2009年2月18日(水) 20:55
by non
何がわからないのか、もう少しわかるように書いてもらえますか。

まず、これはどこまで理解できますか?

段階①
1234は
1*1000+2*100+3*10+4

段階②
((((0+1)*10+2)*10+3)*10+4

段階③
次を順番に実行すると
n=0;
n=n*10+1;
n=n*10+2;
n=n*10+3;
n=n*10+4;

段階④
int s[4]={1,2,3,4};
n=0;
n=n*10+s[0];
n=n*10+s[1];
n=n*10+s[2];
n=n*10+s[3];

段階⑤
int s[4]={1,2,3,4};
n=0;
for(i=0;i<4;i++)
   n=n*10+s;


段階⑥
char st[/url]="1234"
n=0;
for(i=0;i<4;i++)
   n=n*10+(st-0x30);

Re:またまた文字列

Posted: 2009年2月19日(木) 19:17
by 馬鹿太郎
・整数値に変換した値を返すとはどういうことでしょうか?
 僕には1234がそのまま1234を返しているしか見えません。

段階①
1234は
1*1000+2*100+3*10+4

段階②
((((0+1)*10+2)*10+3)*10+4

段階③
次を順番に実行すると
n=0;
n=n*10+1;
n=n*10+2;
n=n*10+3;
n=n*10+4;

段階④
int s[4]={1,2,3,4};
n=0;
n=n*10+s[0];
n=n*10+s[1];
n=n*10+s[2];
n=n*10+s[3];

段階⑤

int s[4]={1,2,3,4};
n=0;
for(i=0;i<4;i++)
n=n*10+s;



段階⑥

char st[/url]="1234"
n=0;
for(i=0;i<4;i++)
n=n*10+(st-0x30);

これはいったい何の計算をしているのですか?
段階②がわかりません

Re:またまた文字列

Posted: 2009年2月19日(木) 19:47
by 馬鹿太郎
if (st >= '0' && st <= '9')

この'0'と'9'は文字コードの0と9を表しているのですか?

no = no * 10 + st - '0'

この'0’は文字コードの0ですよね?どうしてわざわざ0を引いているのですか?
結果は同じなのに・・・

Re:またまた文字列

Posted: 2009年2月19日(木) 19:54
by box
文字'0'と数値の0は異なることを理解してください。
'0'の値は、文字コード体系に応じた、非ゼロの値です。
例えば、ASCIIコードでは、X'30'(十進では48)という値です。

st - '0'
という式は、'0'~'9'のいずれかの値を持っているstから
'0'の値を引くことで、stが'0'からいくつ離れているか、
つまり0~9のいずれかを求める、という意味があります。

結果として、
stが'0'のとき、数値の0
stが'1'のとき、数値の1
以下同様に、
stが'9'のとき、数値の9
が求まります。すなわち、数字の文字('0'~'9')を数値(0~9)に
変換しているのです。

Re:またまた文字列

Posted: 2009年2月19日(木) 20:34
by non
段階② でわからないわけですね。
((((0+1)*10+2)*10+3)*10+4
これを計算すると1234になることは分かりますよね。
式を展開すると
1*1000+2*100+3*10+4 になります。
だから、
1*1000+2*100+3*10+4 =((((0+1)*10+2)*10+3)*10+4
とおなじです。
さて、ここで1000の桁をa、100の桁をb、10の桁をc、1の桁をdとすると
((((0+1)*10+2)*10+3)*10+4=((((0+a)*10+b)*10+c)*10+d
になることはおわかりでしょうか。
これが、理解できるのなら段階③に進んで下さい。

if (st >= '0' && st <= '9')
は書き直すと
if (st >= 48 && st <= 57)
また、
no = no * 10 + st - '0' は
no = no * 10 + st - 48 と同じです。
決して0を引いているわけではありません。
のことです。アスキーコード表は見ましたか?

Re:またまた文字列

Posted: 2009年2月19日(木) 20:41
by 馬鹿太郎
文字'0'と数値の0は異なることを理解してください。

なんか、分かりかけているような・・・
もうちょっと、詳しくお願いします

Re:またまた文字列

Posted: 2009年2月19日(木) 20:57
by box
'0'と'\0'とは異なることも理解してください。
'\0'の値はゼロです。

Re:またまた文字列

Posted: 2009年2月20日(金) 10:15
by non
> 文字'0'と数値の0は異なることを理解してください。
>
> なんか、分かりかけているような・・・
> もうちょっと、詳しくお願いします

みなさんが、たくさん書いてくれているのに、ちょっと失礼じゃないですか?
馬鹿太郎さんが、何がわからないのかが、私にはわからないのです。
何を詳しく書けといっているのか、詳しく書いてください。
馬鹿太郎さんの文面をみれば、小学生ではなさそうですし・・・・・
アスキーコード表は見ましたかと、2回も書いたのに、見ましたとは返事がないじゃないですか。
コード表をみれば、何回も書いたように、'0'はコンピュータの中では、数値の48になっているのだから
0ではないってのは明らかなはずです。

Re:またまた文字列

Posted: 2009年2月20日(金) 21:50
by 無題
char st[4] = {'1','2','3','4'};

の時、
一回目、no == 0,st[0] == '1'なので

 no = 0 * 10 + 49 - 48;'1'=49,'0'=48

と、こうなるので no に 1 が入ります。('1'とは別です。)
二回目は、no == 1,st[1] == '2'なので

 no = 1 * 10 + 50 - 48;'2'=50,'0'=48

で、no == 12 になるってことだと思います。

'a'や'Y'などは、if文の条件に合わないので

 return(-1)ってことだと思いますよ。

的外れor間違ってたらごめんなさい。

Re:またまた文字列

Posted: 2009年2月21日(土) 02:13
by 馬鹿太郎
皆様、ご返答ありがとうございました。
いろいろ、皆様の意見を聞き、プログラムをいじっていたら、理解できました。

non様、大変ありがとうございました。

これから、質問するときは、気をつけたいと思います。