char配列をint型に代入する方法について

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

char配列をint型に代入する方法について

#1

投稿記事 by nana » 12年前

c言語でスタックのプログラムを作成中にchar型の配列の一つにint型の変数を入力使用としましたがうまくいきませんでした。そこでgoolgeで解決方法を調べ一応プログラムが正常に動くまでに至りました。しかし、どうしてこの方法でプログラムが動くようになったのかが理解できません。原理を知っている方がいたらぜひ教えてください。お願いします。

宣言
int num;
char[5];
訂正前
num=data;
訂正後
num=data-'0';

nana

Re: char配列をint型に代入する方法について

#2

投稿記事 by nana » 12年前

まちがえてました。
char data[5];
でした。

zxc
記事: 79
登録日時: 13年前
住所: 日本の背骨(?)あたり

Re: char配列をint型に代入する方法について

#3

投稿記事 by zxc » 12年前

  修正した部分だけ見せられても、「どんなコードで書かれた、どんなプログラムのどこが悪いから、この方法で解決できた!」なんて言える人はそう多くはないと思います。

要するに原理を教えてもらおうとするには、情報が少なすぎませんか、と言いたいのです。


  コードを載せる場合はコードタグをご利用ください。直に書かれても見難いです。

nana

Re: char配列をint型に代入する方法について

#4

投稿記事 by nana » 12年前

コード:

#include<stdio.h>
int max=10;
int stacpointa=0;
int stac[10];

int pop(void);
int push(int a);

int main (void){
	int i=0;
	char data[10];
	int num1,num2,num3;
	printf("数式を入力してください\n");
	scanf("%s",data);

	for(i=0;data[i]!='\0';i++){
		if(data[i]=='+'){
			num1=pop();
			num2=pop();
			push(num1+num2);
		}else if(data[i]=='-'){
			num1=pop();
			num2=pop();
			push(num1-num2);
		}else if(data[i]=='*'){
			num1=pop();
			num2=pop();
			push(num1*num2);
		}else if(data[i]=='/'){
			num1=pop();
			num2=pop();
			push(num1/num2);
		}else{
				alnum3=data[i]-'0';
			push(num3);
		}
	}
	printf("%d\n",pop());
	
return 0;
}

int push(int a){
	if(stacpointa>=max)
		printf("スタックが満杯です\n");
	stac[stacpointa]=a;
	stacpointa++;
}
int pop(void){
	if(stacpointa==0)
		printf("格納された数字がありません\n");
	stacpointa--;
	return stac[stacpointa];
}
ご指摘ありがとうございます。
すいませんでした
投稿方法が間違っていたらすいません

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: char配列をint型に代入する方法について

#5

投稿記事 by softya(ソフト屋) » 12年前

数値と文字の違いは分かりますか?
ここでは、それが一番のポイントです。

あと
alnum3=data-'0';
ってなんでしょう?

さらに補足、折角エラーガードしているのにエラー後の処理が書いてないので意味ないです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

nana

Re: char配列をint型に代入する方法について

#6

投稿記事 by nana » 12年前

何度も申し訳ありません

先ほどあげたプログラムは成功したものです。
エラーガードの意味を知らないのでうまく書けませんが
プログラム失敗時ではalnum3=dataの部分を
alnum3=data
と書いていたのですが
alnum3=data-'0';
書き直したら成功しました。
この理由が知りたいです。
稚拙な文章で本当に申し訳ありません。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: char配列をint型に代入する方法について

#7

投稿記事 by softya(ソフト屋) » 12年前

たぶん、プログラム全体を理解されていない可能性があります。
alnum3はないのでコンパイルは通りません。

>数値と文字の違いは分かりますか?
>ここでは、それが一番のポイントです。

ここが一番重要と書いたのですが、お答え頂けないでしょうか?

>先ほどあげたプログラムは成功したものです。
>エラーガードの意味を知らないのでうまく書けませんが

その答えだと殆どコピペしているとしか思えません。

コード:

    if(stacpointa>=max)
        printf("スタックが満杯です\n");
とかは、なぜ必要なのか答えて頂けますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

nana

Re: char配列をint型に代入する方法について

#8

投稿記事 by nana » 12年前

>ここが一番重要と書いたのですが、お答え頂けないでしょうか?

int型は四バイトの整数でchar型は一バイトの文字だと認識して間す。
普通に値を代入してもできないとおもいます。
なのでいろいろと調べてこの方法にたどり着きましたがどうしてこうなったのかがわかりません。

>その答えだと殆どコピペしているとしか思えません
>とかは、なぜ必要なのか答えて頂けますか?
単純に自分の知識不足です。申し訳ありません。
それは配列が満杯になったのでそれをあらわしているからです。

アバター
雨ガエル
記事: 34
登録日時: 13年前
住所: 新潟
連絡を取る:

Re: char配列をint型に代入する方法について

#9

投稿記事 by 雨ガエル » 12年前

int型は数値を入れますよね。char型は文字を入れますよね。
ですが実際はchar型変数に入っているものも数値です。
各数値に対応する文字が決めてあって、その数値を文字として扱っているわけです。

コード:

num = data[i]-'0';
この時dataに'3'という文字が入っていたとします。
このdataを数値で表すと、 0x33 です。
'0'という文字を数値で表すと、 0x30 です。
ではdataから'0'を引く、すなわち 0x33 から 0x30 を引いたらどうなるでしょうか。
希望どおり3が得られます。

この例はASCIIという文字コードの場合ですが、仕組みはこんなかんじです。

ASCII文字コード表
http://e-words.jp/p/r-ascii.html

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: char配列をint型に代入する方法について

#10

投稿記事 by softya(ソフト屋) » 12年前

>int型は四バイトの整数でchar型は一バイトの文字だと認識して間す。
>普通に値を代入してもできないとおもいます。
>なのでいろいろと調べてこの方法にたどり着きましたがどうしてこうなったのかがわかりません。

そこが間違いです。charも整数の変数なのです。
実は文字は数値として扱われます。なので、charに文字が代入できるのです。
当然intにも代入できます。

一般的なWindowsの環境においてですが、文字は次のような数値として管理されます。
「文字コード表 シフトJIS(Shift_JIS)」 ここの1バイト(半角)の文字コードです。
http://charset.7jp.net/sjis.html
そして数値の文字コードに特徴的な並びが確認できると思います。

※ 豆知識
それとintが4バイトなのはすべての環境で保証されたものではありません。2バイトな環境も存在します。


>単純に自分の知識不足です。申し訳ありません。
>それは配列が満杯になったのでそれをあらわしているからです。

このコードだと満杯になっているのに
stac[stacpointa]=a;
と代入してしまうと思いますが、まずいと思いませんか?


alnum3の件は良かったんですか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

nana

Re: char配列をint型に代入する方法について

#11

投稿記事 by nana » 12年前

>alnum3の件は良かったんですか?
自分の不注意でnum3をalnum3と書いてました。
ご指摘ありがとうございます。

>このコードだと満杯になっているのに
>stac[stacpointa]=a;
>と代入してしまうと思いますが、まずいと思いませんか?
if文はc言語で{}なしの場合下の一行だけ実行するので一応動いてます。
書き方が悪いみたいでした。すいません。

nana

Re: char配列をint型に代入する方法について

#12

投稿記事 by nana » 12年前

雨ガエル さん
ありがとうございます。
何とか理解できました。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: char配列をint型に代入する方法について

#13

投稿記事 by softya(ソフト屋) » 12年前

nana さんが書きました: >このコードだと満杯になっているのに
>stac[stacpointa]=a;
>と代入してしまうと思いますが、まずいと思いませんか?
if文はc言語で{}なしの場合下の一行だけ実行するので一応動いてます。
書き方が悪いみたいでした。すいません。
(1) if(stacpointa>=max)
(2) printf("スタックが満杯です\n");
(3) stac[stacpointa]=a;
(4) stacpointa++;

(1)に来て(2)で止まると思われているようですが、(3)(4)も実行されます。printf("ここに来たよ\n");を(4)の下に入れてみれば分かります。
動いているのは、たまたまであって配列外の内容を破壊しています。
C言語ではありがちですが、けっこう重度のバグです。

【補足】
あと、結構問題だと思いますが、1桁の数値しか扱っていませんが良いんでしょうか?
それに適当な英字を打ち込んだり、()とか書いても間違った形で動くことは良いのでしょうか?

【追記】
ちなみに書いてないので補足しておきますが、このプログラムは逆ポーランド記法の計算式を処理します。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

nana

Re: char配列をint型に代入する方法について

#14

投稿記事 by nana » 12年前

>(1)に来て(2)で止まると思われているようですが、(3)(4)も実行されます。printf("ここに来たよ\n");を(4)の下に入れてみれば分かります。
動いているのは、たまたまであって配列外の内容を破壊しています。
C言語ではありがちですが、けっこう重度のバグです。

何度もありがとうございます。if else文で処理をしてみようと思います。

>あと、結構問題だと思いますが、1桁の数値しか扱っていませんが良いんでしょうか?
それに適当な英字を打ち込んだり、()とか書いても間違った形で動くことは良いのでしょうか?

自分はまだ初心者なのでプログラムはあくまで一桁数字のプログラムを想定して作りました。
自分のスキルが上達したら二ケタ以上の場合や想定外の入力への対処などに挑戦してみようと考えています。


閉鎖

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