C言語 関数にポインタを引数として渡すプログラムについて

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

C言語 関数にポインタを引数として渡すプログラムについて

#1

投稿記事 by Cstudent » 7年前

変なプログラムを書いてるかもしれませんが、すいません。
文字を大文字に変換する出力ができなくて、困ってます。教えて下さい。
#include<stdio.h>
char func(char *p)
{
int n = 0;
char ss[20];
p = ss;

while (ss[20]) {
if (ss[n] == 'a') {
ss[n] = 'A';
}
else
if (ss[n] == 'b') {
ss[n] = 'B';
}
else
n++;
}

白い

Re: C言語 関数にポインタを引数として渡すプログラムについて

#2

投稿記事 by 白い » 7年前

詳細な仕様が分かりませんので、憶測でコーディングしましたが、

コード:

char func(char *p){
	int i;
	
	if(p==NULL) return 1;
	
	for(i=0;p[i]!='\0';i++) if(p[i]>='a' && p[i]<='z') p[i]='A'+p[i]-'a';
	
	return 0;
}


こういう事がしたかったのですかね。

Cstudent

Re: C言語 関数にポインタを引数として渡すプログラムについて

#3

投稿記事 by Cstudent » 7年前

char func(char *p){
    int i;
   
    if(p==NULL) return 1;
   
    for(i=0;p!='\0';i++) if(p>='a' && p<='z') p='A'+p-'a';
   
    return 0;
}

NULLの定義に関するエラーがでてきたのですが、NULLの定義の仕方も教えていただけると助かります。

白い変人

Re: C言語 関数にポインタを引数として渡すプログラムについて

#4

投稿記事 by 白い変人 » 7年前

stdio.h上で定義されていると思うので、

コード:

 
#include <stdio.h>
を1行目に追加すれば良いだけだと思いますが。

因みに、NULLについては0と定義されていると思いますよ。

Cstudent

Re: C言語 関数にポインタを引数として渡すプログラムについて

#5

投稿記事 by Cstudent » 7年前

すいません。その通りでした。ほかにプログラム文で分からないことがあるのですが、
p = 'A' + p - 'a';の文は、これでなぜ小文字を大文字に変換できるのか?教えて下さい。よろしくお願いします。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: C言語 関数にポインタを引数として渡すプログラムについて

#6

投稿記事 by みけCAT » 7年前

ソースコードを提示する際は、BBCodeが有効な(無効にしない)状態で、
BBCodeのcodeタグの開始タグと終了タグの組(開始タグが先)で囲んでいただけると、
見やすくてありがたいです。
Cstudent さんが書きました:while (ss[20]) {
ssの要素数は20なので、有効な添字は0~19だけであり、このようにss[20]を読み込むのは未定義動作です。
ss[n]とすると改善するでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

白い変人

Re: C言語 関数にポインタを引数として渡すプログラムについて

#7

投稿記事 by 白い変人 » 7年前

では、ASCIIコード表を見て、トレースしてみて下さい。
それでもどうしても手も足も出なかったら、再度私から解説致しましょう。

ヒントとして、'A'や'a'は数値と捉えて下さい。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: C言語 関数にポインタを引数として渡すプログラムについて

#8

投稿記事 by みけCAT » 7年前

みけCAT さんが書きました:
Cstudent さんが書きました:while (ss[20]) {
ssの要素数は20なので、有効な添字は0~19だけであり、このようにss[20]を読み込むのは未定義動作です。
ss[n]とすると改善するでしょう。
ごめんなさい。
そもそもssは初期化されていない自動変数なので、値は不定であり、その要素の値を利用した計算をするのも未定義動作ですね。
入力のpの値を全く使わずに消してしまうのはおかしいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Cstudent

Re: C言語 関数にポインタを引数として渡すプログラムについて

#9

投稿記事 by Cstudent » 7年前

すいません。プログラムは、見えやすいように気を付けます。

ASCIIコードで、数値的に考えたら、小文字の文字コード同士で、互いに打ち消しあって、大文字の文字コードだけが、残るから。という理由だからですか?

文字コードを使うときと、使わない時の違いの根本的な部分が良く分からいのですが、教えて下さい。

白い変人

Re: C言語 関数にポインタを引数として渡すプログラムについて

#10

投稿記事 by 白い変人 » 7年前

ASCII CODE 表を見たのならば、p が'a'~'z' (小文字) である場合、 p-'a'は 0~25の値になる事は理解出来るよね?

その値を'A' (大文字) に加算すれば、上記小文字の'a'から数えて何番目かという値が、大文字の'A'から数えて何番目かという値に変換出来るという事です。

因みに、この方法を使えば、ASCII CODE 以外でも、'A'~'Z'、'a'~'z'が順に配置されているコード(一般的なコードは全てそういう並び) ならばどの様なコードの環境でも理論上は流用可能になります。

白い変人

Re: C言語 関数にポインタを引数として渡すプログラムについて

#11

投稿記事 by 白い変人 » 7年前

>文字コードを使うときと、使わない時の違いの根本的な部分が良く分からいのですが、教えて下さい。

文字コードとは、実用上は既に規格化された文字コードを使う事が一般的なので、使う/使わない は、まず、マシンの環境に依存すると言えるでしょう。

貴方がこの掲示板に文字を打っていると思いますが、その文字の表現にも文字コードが使われているだけで、実際は0と1の数値でしかありません。

ただ、コンピュータ上では、例えば数値を表現する場合には、0と1が扱えればいいケースでは1bitで済む話なので、態々1byte要して'0'と'1'として計算資源を無駄にする必要が無いという意味で、プログラマは使い分けが必要でしょう。

但し、状況次第では、文字列の数字を数値として認識させて計算させる場合もありますので、上記が全てと言う訳では有りません。

また、プログラマが混乱しない事を優先させる為に、敢えて数値を文字として表現する場合もあるにはあると言えます。

Cstudent

Re: C言語 関数にポインタを引数として渡すプログラムについて

#12

投稿記事 by Cstudent » 7年前

C言語プログラムで自分の知らなかった新たな見方を学ぶことができました。
とても分かりやすい解説をありがとうございます。

Cstudent

Re: C言語 関数にポインタを引数として渡すプログラムについて

#13

投稿記事 by Cstudent » 7年前

みけCATさんのして下さったた未定義動作は、どう修正したらいいのですか?
よく分からなかったので、お時間がありましたら、アドバイス又はヒントをお願いします。

かずま

Re: C言語 関数にポインタを引数として渡すプログラムについて

#14

投稿記事 by かずま » 7年前

Cstudent さんが書きました:みけCATさんのして下さったた未定義動作は、どう修正したらいいのですか?
未定義動作にならないようにするには、どう修正したらよいかですね。

まずは、配列の要素だけを参照すればよいということです。

char ss[20]; と、20個の char の要素を確保したら、
ss[0], ss[1], ... ss[19] の 20個の要素しか参照できないので、
ss[20] のように範囲外の要素を参照してはいけないということです。

次に、変数は初期化や代入などにより値を格納してから、
その値を参照するということです。

ss[20] を ss[n] や ss[0] に変更しても、そこにはどんな値が
入っているかわからなので、使ってはいけないということです。

結局、char ss[20]; そのものを使用しないように修正すればよいと思います。

関数 func の仕様(どのように動けばよいのか)を明確にしてください。

また、関数 func を呼び出すプログラムを提示してください。
それは、おそらく main 関数でしょうが、とにかく、それがないと
デバッグもできないと思います。

Cstudent

Re: C言語 関数にポインタを引数として渡すプログラムについて

#15

投稿記事 by Cstudent » 7年前

配列の要素数を超えないようにすればいいんですね、みけCATさん、ありがとうございます。再び、文字列を入力して、そのまま出力するもの、コピーした後に出力するもの、小文字のaをA,小文字のbをB,に出力するプログラムを作ったのですが、ビルドエラーがかなりでて、よく分かりません。教えて下さい。

(すいません、ソースコードを選択したあとにスタイルを選択する操作も分からなくて、見えにくくなってしまいました)



#include<stdio.h>
char replace(char *p)
{
void replace(char*p);

while (*p) {//文字列終端まで
if (*p >= 'a' && *p <= 'b') {
//x~yの文字の時
*p += 'C' - 'a';//xをXに変換するために必要な値を加える
}
p++;//次の文字へ
*p += 'B' - 'b';
return *p;
}
char copy(char ss[20],char cp[20])
{
void copy(char ss[20],char cp[20]);
char cp[20], char ss[20];
int i;
for (i = 0; i < 20; i++) {
ss = cp;
}
}
int main(void) {
char ss[20];
char cp[20];

printf("文字列(アルファベット)を入力してください\n");
scanf_s("%s", ss, 20);
printf("入力された文字列: %s\n", ss);
copy(ss, cp);
printf("コピーされた文字列: %s\n", cp);
replace(ss);
printf("置換された文字列: %s\n", ss);
return 0;
}

かずま

Re: C言語 関数にポインタを引数として渡すプログラムについて

#16

投稿記事 by かずま » 7年前

Cstudent さんが書きました: (すいません、ソースコードを選択したあとにスタイルを選択する操作も分からなく
て、見えにくくなってしまいました)
[color=#0000ff]ではなく,[code=c]と書いてください。閉じるのは[/code]

コード:

#include<stdio.h>
char replace(char *p)
{
	void replace(char*p);

	while (*p) {//文字列終端まで
		if (*p >= 'a' && *p <= 'b') {
			//x~yの文字の時
			*p += 'C' - 'a';//xをXに変換するために必要な値を加える
		}
		p++;//次の文字へ
		*p += 'B' - 'b';
		return *p;
	}
	char copy(char ss[20],char cp[20])
	{
		void copy(char ss[20],char cp[20]);
		char cp[20], char ss[20];
		int i;
		for (i = 0; i < 20; i++) {
			ss[i] = cp[i];
		}
	}
	int main(void) {
		char ss[20];
		char cp[20];

		printf("文字列(アルファベット)を入力してください\n");
		scanf_s("%s", ss, 20);
		printf("入力された文字列: %s\n", ss);
		copy(ss, cp);
		printf("コピーされた文字列: %s\n", cp);
		replace(ss);
		printf("置換された文字列: %s\n", ss);
		return 0;
	}
アルファベットは 'a' から 'b' でなく、'a' から 'z' ですよね。
'C' は何ですか?
copy の向きにも注意。

コード:

#include <stdio.h>

char replace(char *p)
{
	while (*p) {//文字列終端まで
		if (*p >= 'a' && *p <= 'z') {
			//x~yの文字の時
			*p += 'A' - 'a';//xをXに変換するために必要な値を加える
		}
		p++;//次の文字へ
	}
	return 0;
}

void copy(char ss[20], char cp[20])
{
	int i;
	for (i = 0; i < 20; i++) {
		ss[i] = cp[i];
	}
}

int main(void)
{
	char ss[20];
	char cp[20];

	printf("文字列(アルファベット)を入力してください\n");
	scanf_s("%s", ss, 20);
	printf("入力された文字列: %s\n", ss);
	copy(cp, ss);
	printf("コピーされた文字列: %s\n", cp);
	replace(ss);
	printf("置換された文字列: %s\n", ss);
	return 0;
}
どこが悪かったのかを説明してください。

Cstudent

Re: C言語 関数にポインタを引数として渡すプログラムについて

#17

投稿記事 by Cstudent » 7年前

copyの関数の定義や関数定義後の左かっこに対応するものがないこと、間違っている原因だとビルドエラーにはかかれているのですが、修正方法が分かりません。

コード:

#include<stdio.h>

#include<stdio.h>
void replace(char *p);

void copy(char ss[20], char cp[20]);


	int main(void) {
		char ss[20];
		char cp[20];

		printf("文字列(アルファベット)を入力してください\n");
		scanf_s("%s", ss, 20);
		printf("入力された文字列: %s\n", ss);
		copy(ss, cp);
		printf("コピーされた文字列: %s\n", cp);
		replace(ss);
		printf("置換された文字列: %s\n", ss);
		return 0;
	}
         
	
	void replace(char*p)
	{

		while (*p) {//文字列終端まで
			if (*p >= 'a' && *p <= 'z') {
				//x~yの文字の時
				*p += 'C' - 'a';//xをXに変換するために必要な値を加える
			}
			p++;//次の文字へ
			*p += 'B' - 'b';
		}
void copy(char ss[], char cp[])	
{			int i;
			for (i = 0; i < 20; i++) {

				ss[i] = cp[i];
			}

		}

かずま

Re: C言語 関数にポインタを引数として渡すプログラムについて

#18

投稿記事 by かずま » 7年前

Cstudent さんが書きました:copyの関数の定義や関数定義後の左かっこに対応するものがないこと、間違っている原因だとビルドエラーにはかかれているのですが、修正方法が分かりません。
括弧の対応が分かるようにインデント(字下げ)をちゃんとしましょう。

コード:

#include<stdio.h>
 
#include<stdio.h>   // この行は不要
void replace(char *p);
void copy(char ss[20], char cp[20]);
 
int main(void) {
	char ss[20];
	char cp[20];

	printf("文字列(アルファベット)を入力してください\n");
	scanf_s("%s", ss, 20);
	printf("入力された文字列: %s\n", ss);
	copy(ss, cp);
	printf("コピーされた文字列: %s\n", cp);
	replace(ss);
	printf("置換された文字列: %s\n", ss);
	return 0;
}
	 
void replace(char*p)
{
	while (*p) {//文字列終端まで
		if (*p >= 'a' && *p <= 'z') {
			//x~yの文字の時
			*p += 'C' - 'a';//xをXに変換するために必要な値を加える
		}
		p++;//次の文字へ
		*p += 'B' - 'b';
	}
}  // この } がなかった ★★★★★★

void copy(char ss[], char cp[]) 
{
	int i;
	for (i = 0; i < 20; i++) {
		ss[i] = cp[i];
	}
}
で、'C' や 'B' は何ですか?

Cstudent

Re: C言語 関数にポインタを引数として渡すプログラムについて

#19

投稿記事 by Cstudent » 7年前

 すいません。Cではなく、Aの間違えです。実行結果も意味不明なものが出力されたのですが、なんでこんな結果になるのでしょうか?

コード:

#include<stdio.h>
 
#include<stdio.h>   // この行は不要
void replace(char *p);
void copy(char ss[20], char cp[20]);

int main(void) {
    char ss[20];
    char cp[20];
 
    printf("文字列(アルファベット)を入力してください\n");
    scanf_s("%s", ss, 20);
    printf("入力された文字列: %s\n", ss);
    copy(ss, cp);
    printf("コピーされた文字列: %s\n", cp);
    replace(ss);
    printf("置換された文字列: %s\n", ss);
    return 0;
}
     
void replace(char*p)
{
    while (*p) {//文字列終端まで
        if (*p >= 'a' && *p <= 'z') {
            //x~yの文字の時
            *p += 'A' - 'a';//xをXに変換するために必要な値を加える
        }
        p++;//次の文字へ
        *p += 'B' - 'b';
    }
}  // この } がなかった ★★★★★★
 
void copy(char ss[], char cp[]) 
{
    int i;
    for (i = 0; i < 20; i++) {
        ss[i] = cp[i];
    }
}

文字列(アルファベット)を入力してください
abcdefabcde
入力された文字列: abcdefabcde
コピーされた文字列: フフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフフ卆T。\
置換された文字列: フャャャャャャャャャャャャャャャャャャャャャャャ[・・リモ燼壟矜珥ミ+癢3癆リモ・

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: C言語 関数にポインタを引数として渡すプログラムについて

#20

投稿記事 by みけCAT » 7年前

Cstudent さんが書きました:なんでこんな結果になるのでしょうか?
copy関数に渡している引数が逆であり、せっかく読み込んだデータを不定の値で上書きしているのが悪いでしょう。

さらに、ここを修正しても、このコードには以下の問題もあります。
  • *p <= 'z'のzが全角である。複数バイトの文字定数は処理系定義の値になります。
  • *p += 'B' - 'b';で文字をぶっ壊している。特に、最後の'\0'をぶっ壊すことで、文字列の外側を読み込み、未初期化の自動変数の値を計算に使用して未定義動作になります。
    また、配列の範囲外を読み書きするという未定義動作(Segmentation Faultの原因にもなる)も起こり得ます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Cstudent

Re: C言語 関数にポインタを引数として渡すプログラムについて

#21

投稿記事 by Cstudent » 7年前

引数を逆にして、zを半角にして、あとは、p++をつけて、こんな感じになりました。未定義動作がおこっていることが、まだ理解できていないんだと思いました。アドバイスありがとうございます。

コード:


#include<stdio.h>

		void replace(char *p);
		void copy(char *cp, char *ss);

		int main(void) {
			char ss[20];
			char cp[20];

			printf("文字列(アルファベット)を入力してください\n");
			scanf_s("%s", ss, 20);
			printf("入力された文字列: %s\n", ss);
			copy(cp, ss);
			printf("コピーされた文字列: %s\n",ss);
			replace(ss);
			printf("置換された文字列: %s\n", ss);
			return 0;
		}

		void replace(char*p)
		{
			while (*p) {//文字列終端まで
				if (*p >= 'a' && *p <= 'z') {
					//x~yの文字の時
					*p += 'A' - 'a';//xをXに変換するために必要な値を加える
				}
				p++;//次の文字へ
				*p += 'B' - 'b';
				p++;
			}
		}// この } がなかった ★★★★★★

		void copy(char cp[],char ss[] )
		{
			int i;
			for (i = 0; i < 20; i++) {
				ss = cp;
				 ss[i]=cp[i];
			}
		}

アバター
purin52002
記事: 235
登録日時: 7年前
連絡を取る:

Re: C言語 関数にポインタを引数として渡すプログラムについて

#22

投稿記事 by purin52002 » 7年前

引数を逆にしたのはいいのですが、読み込んだデータを不定の値で上書きしている部分が直っていないのでちゃんと動かないような気がします^^;

おそらくですが、cpにssの値をコピーしたいのはないでしょうか?
だとするとcpが左辺に来るべきだと思います。
[hr]
質問者さんに質問するのもおかしいですが、

コード:

*p+='B'-'b';
にはどんな意味があるんですか?

'A'-'a'の意味は分かったんですけど'B'-'b'の意味が分かりませんでしたorz
次の文字だから'B'-'b'っていうことですか?
c++初心者を自負しています。
質問者さんには今後私にプログラミングを教えてくれるようにやさしく丁寧に教えるつもりです。ぎぶあんどていく^p^
回答者さんには精一杯感謝します。ぎぶおんりー^p^

box
記事: 2002
登録日時: 13年前

Re: C言語 関数にポインタを引数として渡すプログラムについて

#23

投稿記事 by box » 7年前

purin52002 さんが書きました:
'A'-'a'の意味は分かったんですけど'B'-'b'の意味が分かりませんでしたorz
少なくとも、ASCIIコードにおいては、
'A' - 'a'
'B' - 'b'
'C' - 'c'
...
'Z' - 'z'
は、どれも同じはずです。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

Cstudent

Re: C言語 関数にポインタを引数として渡すプログラムについて

#24

投稿記事 by Cstudent » 7年前

20個以内で、アルファベットを読み込んで、特定の2つの小文字を大文字にかえるプログラムが作りたかったので、特に意味はありません。
プログラムは、ご指摘の通り、値が不定になっているとことは、出力がおかしなことになっていて、修正方法がまだわからないです。
なにか、アドバイスがあればよろしくお願いします。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: C言語 関数にポインタを引数として渡すプログラムについて

#25

投稿記事 by みけCAT » 7年前

Cstudent さんが書きました:引数を逆にして
どうしてcopy関数にせっかく渡されたssをcpで上書きしてしまうコードを追加したのですか?
Cstudent さんが書きました:あとは、p++をつけて
どうしてそんなことをしたのですか?
Cstudent さんが書きました:20個以内で、アルファベットを読み込んで、特定の2つの小文字を大文字にかえるプログラムが作りたかったので、特に意味はありません。
何が20個以内なのですか?
「特定の2つの小文字」とは何ですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Cstudent

Re: C言語 関数にポインタを引数として渡すプログラムについて

#26

投稿記事 by Cstudent » 7年前

みけCAT さんが書きました:
Cstudent さんが書きました:引数を逆にして
どうしてcopy関数にせっかく渡されたssをcpで上書きしてしまうコードを追加したのですか?
まだ、理解がおいついておらず、余計なことをしてしまいました。
Cstudent さんが書きました:あとは、p++をつけて
どうしてそんなことをしたのですか?
ポインタの位置を順次ずらしていく必要があるのかな?と思って追加しました。
Cstudent さんが書きました:20個以内で、アルファベットを読み込んで、特定の2つの小文字を大文字にかえるプログラムが作りたかったので、特に意味はありません。
何が20個以内なのですか?
入力したアルファベットの個数のことです。
「特定の2つの小文字」とは何ですか?
このプログラムでは、aとbという小文字を必ず入力して大文字に変換したいと思っています。

コード:

#include<stdio.h>

void replace(char *p);
void copy(char *cp, char *ss);

int main(void) {
	char ss[20];
	char cp[20];

	printf("文字列(アルファベット)を入力してください\n");
	scanf_s("%s", ss, 20);
	printf("入力された文字列: %s\n", ss);
	copy(cp, ss);
	printf("コピーされた文字列: %s\n", cp);
	replace(ss);
	printf("置換された文字列: %s\n", ss);
	return 0;
}

void replace(char*p)
{
	while (*p) {//文字列終端まで
		if (*p >= 'a' && *p <= 'z') {
			//x~yの文字の時
			*p += 'A' - 'a';//xをXに変換するために必要な値を加える
		}
		p++;//次の文字へ
		*p += 'B' - 'b';
		

	}
}// この } がなかった ★★★★★★

void copy(char cp[], char ss[])
{
	int i;
	for (i = 0; i < 20; i++) {
		
		cp[i] = ss[i];
	}
}
置換された文字列の出力に、不定のデータが上書きされないようにするには、どうしたらいいですか?。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: C言語 関数にポインタを引数として渡すプログラムについて

#27

投稿記事 by みけCAT » 7年前

Cstudent さんが書きました:
Cstudent さんが書きました:引数を逆にして
どうしてcopy関数にせっかく渡されたssをcpで上書きしてしまうコードを追加したのですか?
まだ、理解がおいついておらず、余計なことをしてしまいました。
なるほど、わかりました。
Cstudent さんが書きました:
Cstudent さんが書きました:あとは、p++をつけて
どうしてそんなことをしたのですか?
ポインタの位置を順次ずらしていく必要があるのかな?と思って追加しました。
それはすでに1個目のp++で実現されています。
さらにずらす必要はありません。
Cstudent さんが書きました:
Cstudent さんが書きました:20個以内で、アルファベットを読み込んで、特定の2つの小文字を大文字にかえるプログラムが作りたかったので、特に意味はありません。
何が20個以内なのですか?
入力したアルファベットの個数のことです。
アルファベットの入力を20個まで受け付ける場合、最後のナル文字を含めて21要素以上確保しなければいけません。
Cstudent さんが書きました:「特定の2つの小文字」とは何ですか?
このプログラムでは、aとbという小文字を必ず入力して大文字に変換したいと思っています。
任意の英アルファベットの小文字を大文字に変換するプログラムなら、aとbも大文字に変換できるでしょう。

[hr]
purin52002さんも質問していますが、なぜ*p += 'B' - 'b';という文を置いているのですか?
この文は無条件で文字の変換を行うため、ナル文字を破壊し、前述の通り未定義動作の原因になるので有害です。
小文字を大文字にする操作はp++;の前にあるif文でできているはずです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Cstudent

Re: C言語 関数にポインタを引数として渡すプログラムについて

#28

投稿記事 by Cstudent » 7年前

Cstudent さんが書きました:
Cstudent さんが書きました:あとは、p++をつけて
どうしてそんなことをしたのですか?
ポインタの位置を順次ずらしていく必要があるのかな?と思って追加しました。
それはすでに1個目のp++で実現されています。
さらにずらす必要はありません。

同じことを2回命令してしまっていたんですね。
Cstudent さんが書きました:
Cstudent さんが書きました:20個以内で、アルファベットを読み込んで、特定の2つの小文字を大文字にかえるプログラムが作りたかったので、特に意味はありません。
何が20個以内なのですか?
入力したアルファベットの個数のことです。
アルファベットの入力を20個まで受け付ける場合、最後のナル文字を含めて21要素以上確保しなければいけません。

ナル文字というのも要素数に含めなければ、いけないんですね。分かりました。


[hr]
purin52002さんも質問していますが、なぜ*p += 'B' - 'b';という文を置いているのですか?
この文は無条件で文字の変換を行うため、ナル文字を破壊し、前述の通り未定義動作の原因になるので有害です。
小文字を大文字にする操作はp++;の前にあるif文でできているはずです。[/quote]

この文は無条件で文字の変換を行うのは、どうしてですか?
小文字のbの時に限った場合にならない理由が分かりません。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: C言語 関数にポインタを引数として渡すプログラムについて

#29

投稿記事 by みけCAT » 7年前

Cstudent さんが書きました:この文は無条件で文字の変換を行うのは、どうしてですか?
小文字のbの時に限った場合にならない理由が分かりません。
小文字のbの時に限った場合にする、というコードも他の条件も入っていないからです。
もしもこの文(*p += 'B' - 'b';)が小文字のbに限るのであれば、
どうしてその前にある*p += 'A' - 'a';には「aの文字の時」ではなく「x~yの文字の時」というコメントがあるのですか?
(x~yというのも間違いですが)
Cstudent さんが書きました:

コード:

		if (*p >= 'a' && *p <= 'z') {
			//x~yの文字の時
			*p += 'A' - 'a';//xをXに変換するために必要な値を加える
		}
という部分では、(ASCIIのような英アルファベットが連続して順番に並んでいる文字コードにおいて)文字が小文字の英アルファベットかどうかを判定するif文があり、
文字が小文字の英アルファベットのときに限って足し算、すなわち文字の変換が実行されます。

しかし、
Cstudent さんが書きました:

コード:

		*p += 'B' - 'b';
という部分では、そのようなif文は存在しないので、全ての文字に対して足し算、すなわち文字の変換が実行されます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Cstudent

Re: C言語 関数にポインタを引数として渡すプログラムについて

#30

投稿記事 by Cstudent » 7年前

みけCAT さんが書きました:
Cstudent さんが書きました:この文は無条件で文字の変換を行うのは、どうしてですか?
小文字のbの時に限った場合にならない理由が分かりません。
小文字のbの時に限った場合にする、というコードも他の条件も入っていないからです。
もしもこの文(*p += 'B' - 'b';)が小文字のbに限るのであれば、
どうしてその前にある*p += 'A' - 'a';には「aの文字の時」ではなく「x~yの文字の時」というコメントがあるのですか?
(x~yというのも間違いですが)

コメントも間違っていたんですね。a~zの小文字が大文字に変換されるプログラムで、bに限った場合のコードは書かれていないですね。いろいろ勘違いをしていました。

Cstudent さんが書きました:

コード:

		if (*p >= 'a' && *p <= 'z') {
			//x~yの文字の時
			*p += 'A' - 'a';//xをXに変換するために必要な値を加える
		}
という部分では、(ASCIIのような英アルファベットが連続して順番に並んでいる文字コードにおいて)文字が小文字の英アルファベットかどうかを判定するif文があり、
文字が小文字の英アルファベットのときに限って足し算、すなわち文字の変換が実行されます。

しかし、
Cstudent さんが書きました:

コード:

		*p += 'B' - 'b';
という部分では、そのようなif文は存在しないので、全ての文字に対して足し算、すなわち文字の変換が実行されます。
返信遅くなり、申し訳ありません。if文から外れていると、ご指摘を受けてようやく理解できました。
遅くまで、質問にお答え頂き、感謝いたします。本当にありがとうございました。

返信

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