質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

6回答

1542閲覧

文字列をポインタなしで関数の受け渡しができるのか?

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2020/05/21 05:13

C言語でポインタについて質問です。以下のコードは小文字を大文字に変換するプログラムです。
main関数で配列の文字列を宣言した際に、その配列をポインタなしで、そのまま、関数に受け渡しして、変換するようにはできませんか?
以下のコードでいえば、
char型bufferのアドレスの値を*ptrに代入せずにそのまま、bufferとして関数に受け渡しできるようにしたい。ということです。
たとえば 関数 change_letter(char buffer)として、文字列を受け取り、受け取った文字列をchange_letterの関数内で大文字に変えて出力をする。という感じにしたいです。
他のサイトを見てみると、メイン関数内で実行か、ポインタで関数の受け渡しの二通りしかないので、まだ初心者なのでどのように実行すればよいかわからないです。

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> void change_letter(char* str) { *str = *str - 'a' + 'A'; } void main() { char buffer[128]; char* ptr = buffer; scanf("%s", buffer); printf("%s\n", ptr); while (*ptr != 0) { change_letter(ptr); ptr++; printf("%s\n", buffer); } }

以下が自分の実行したいコードです。change_letter(buffer)でエラーがでて、どのように解決できればよいかわからない状態です。ご協力お願いします。

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> void change_letter(char buffer ) { while (buffer != 0) { buffer = buffer - 'a' + 'A'; printf("%s\n", buffer); } } void main() { char buffer[128]; scanf("%s", buffer); printf("%s\n", buffer ); change_letter(buffer); }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答6

0

お望みの内容とは違うと思いますが・・・
配列を構造体(struct)に入れて構造体を渡すと、構造体の内容がコピーされて渡ります。
データ領域をコピーする分、処理時間は遅くなります。

c

1#include <stdio.h> 2 3struct text { 4 char buffer[128]; 5}; 6 7void change_letter(struct text text) { 8 for (int i = 0; text.buffer[i] != '\0'; i++) { 9 if ('a' <= text.buffer[i] && text.buffer[i] <= 'z') 10 text.buffer[i] = text.buffer[i] - 'a' + 'A'; 11 } 12 printf("change: %s\n", text.buffer); 13} 14 15void main() { 16 struct text text; 17 scanf("%s", text.buffer); 18 change_letter(text); 19 printf("original: %s\n", text.buffer); 20}

実行結果:

hello change: HELLO original: hello

投稿2020/05/21 09:42

編集2020/05/21 09:57
shiracamus

総合スコア5406

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

こんにちは。

まず、C言語には文字列を表現するデータ型が存在しません。
代わりにchar型の配列でNULL終端したデータ構造を「文字列」として使います。
そして、C言語では配列を関数へパラメータとして渡すには配列先頭のポインタを渡すしかありません。

ですので、「文字列をポインタなしで関数の受け渡しができるのか?」への回答は「事実上できません」となります。
しかし、やりたいことは以下の通りではないですか?

C

1#define _CRT_SECURE_NO_WARNINGS 2#include <stdio.h> 3 4void change_letter(char* buffer ) 5{ 6 while (*buffer != 0) 7 { 8 *buffer = *buffer - 'a' + 'A'; 9 ++buffer; 10 } 11} 12 13int main() 14{ 15 char buffer[128]; 16 17 scanf("%s", buffer); 18 printf("%s\n", buffer ); 19 20 change_letter(buffer); 21 printf("%s\n", buffer); 22}

wandbox

投稿2020/05/21 05:39

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/05/22 02:25

やはり、配列の値を渡すには、ポインタを用いて渡すしか方法がなさそうですね。整数を渡すときには、値渡しぽいのができたので、文字列だったらと試みましたが… すいません、そのコードはbufferの配列先頭要素を渡していますか?
Chironian

2020/05/22 04:44

> そのコードはbufferの配列先頭要素を渡していますか? 厳密には、bufferは配列先頭要素のアドレスを渡しています。 そのアドレスの指す先が要素1個だけなのか、複数あるのかはプログラマーが責任を持って管理する必要があります。残念ながら、C言語処理系はこの件に関してほとんどサポートがありません。
ttb

2020/05/26 01:34

char buffer[128]; chsr* ptr = buffer; のとき、 ptr buffer &buffer[0] は全て同じです(配列の先頭要素のアドレス)。 文字列処理関数に渡す時は buffer の表記を使うのが一般的だと思いますが、ハードウェア似よる制約があるとか、様々な事情があるときはこの限りではないかと。 ちなみにC言語の文字列は、ヌル文字(¥0)で終わらないといけない(無いと文字列配列の終端が分からない)ので、1文字であっても、配列に入れるのが原則です。(これも事情があるときはこの限りではないですが)
guest

0

ベストアンサー

main関数で配列の文字列を宣言した際に、その配列をポインタなしで、そのまま、関数に受け渡しして、変換するようにはできませんか?

残念ながら、C言語では(一部の例外を除いて)配列を式に登場させた場合、それは配列の先頭要素へのポインタとして解釈されます。

上のコードで、printf("%s\n", ptr);printf("%s\n", buffer);と書いても問題なく動きますが、それは全く同じポインタを渡しているからです。

投稿2020/05/21 05:17

maisumakun

総合スコア146018

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2020/05/21 05:18

void change_letter(char[] str)のような仮引数宣言は可能ですが、意味的にはvoid change_letter(char* str)と全く同じです。
退会済みユーザー

退会済みユーザー

2020/05/22 02:27

それは両者とも配列の先頭要素のアドレスを受け取っていることとおなじですか?
guest

0

呼び出し元の変数の値は変えたくない、つまり値渡しをしたいということでしょうか。
であるならchar型配列の場合はできません。
必ずポインタ渡しになります。
しかしやりたいことの内容からして元の値を変える必要はないので、ポインタ渡しでも問題ないと思いますが。

どうしても値渡しにしたいのであれば構造体にすれば可能です。

c

1struct TMP { 2 char buffer[128]; 3}; 4 5void main() { 6 struct TMP tmp; 7 change_letter(tmp); 8} 9 10void change_letter(struct TMP tmp) 11{ 1213}

投稿2020/05/21 05:31

ttyp03

総合スコア17000

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

単純に仮引数の型をchar→char*にした上で、同処理にすればいいです。

投稿2020/05/21 05:16

編集2020/05/21 05:17
HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

次のように書けば、配列しか知らない人にはポインタを使っていることを感じさせないでしょう。

C

1#define _CRT_SECURE_NO_WARNINGS 2#include <stdio.h> 3 4void change_letter(char buffer[]) 5{ 6 for (int i = 0; buffer[i]; i++) 7 buffer[i] -= 'a' - 'A'; 8} 9 10int main(void) 11{ 12 char buffer[128]; 13 scanf("%127s", buffer); 14 printf("%s\n", buffer); 15 change_letter(buffer); 16 printf("%s\n", buffer); 17}

投稿2020/05/26 03:34

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問