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

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

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

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

Q&A

解決済

4回答

781閲覧

C言語の配列の関数間の処理について

karasuma

総合スコア39

C

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

0グッド

0クリップ

投稿2022/10/15 01:40

C言語の配列の処理について

関数に配列を渡して処理し、メインで表示するプログラムの書き方について
・どの書き方が一番いいですか?それぞれのメリットデメリットはありますか?
・配列の受け渡しは下記の方法以外にありますか?
・コード2で宣言しているグローバル変数bufについてstaticを付けるべき場面が分かりません。どういった場面で使うべきですか?

該当のソースコード

C

1//1 2#include<stdio.h> 3char* func(char * buff){ 4 for (size_t i = 0; i < 64; i++) 5 { 6 buff[i] = buff[i] + 1; 7 } 8 return buff; 9} 10int main(void){ 11 char buf[64]; 12 for (size_t i = 0; i < 64; i++) 13 { 14 buf[i] = i + 0x30; 15 } 16 17 char *result = func(buf); 18 19 for (size_t i = 0; i < 64; i++) 20 { 21 printf("%c ",buf[i]); 22 } 23 printf("\n"); 24}

C

1//2 2#include<stdio.h> 3static char buf[64]; 4void func(){ 5 for (size_t i = 0; i < 64; i++) 6 { 7 buf[i] = buf[i] + 1; 8 } 9} 10int main(void){ 11 for (size_t i = 0; i < 64; i++) 12 { 13 buf[i] = i + 0x30; 14 } 15 16 func(); 17 18 for (size_t i = 0; i < 64; i++) 19 { 20 printf("%c ",buf[i]); 21 } 22 printf("\n"); 23}

C

1//3 2#include<stdio.h> 3void func(char * buff,int buff_size){ 4 for (size_t i = 0; i < buff_size; i++) 5 { 6 buff[i] = buff[i] + 1; 7 } 8} 9int main(void){ 10 char buf[64]; 11 for (size_t i = 0; i < 64; i++) 12 { 13 buf[i] = i + 0x30; 14 } 15 16 func(buf,64); 17 18 for (size_t i = 0; i < 64; i++) 19 { 20 printf("%c ",buf[i]); 21 } 22 printf("\n"); 23}

結果

./main 1 2 3 4 5 6 7 8 9 : ; < = > ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ \ ] ^ _ ` a b c d e f g h i j k l m n o p

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

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

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

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

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

jimbe

2022/10/15 04:51

どのような問題があるのでしょうか。 https://teratail.com/help/avoid-asking >問題・課題が含まれていない質問 >teratailは困っている人の質問を解決するサービスです。そのため、漠然とした興味から票を募るような質問や、意見の主張をすることを目的とした投稿は推奨していません。 > >何か困っている理由があり、最適解を見つける為の知見を得たい場合は、その理由や何が知りたいのかを明確に記述してください。 >悪い例:「オススメの開発環境構築方法を教えてください」 >良い例:「Dockerで開発環境を構築していて、ファイルの書き込みができません」
fana

2022/10/17 01:23

(もうBAが選ばれてしまっているけど)なんか話がぼんやりしていて,何を訊きたい話なのかがよくわからない. 少なくとも,この質問文を見た読み手には > グローバル変数を安易に多用する といった話題を含む話だとは読み取れないと思う. (上記引用は,BAになってる質問へのコメントより抜粋) そもそも本件の話自体が > 関数に配列を渡して処理し、メインで表示するプログラムの書き方について… っていう書き出しになってるから,逆に「極めて限定的な範囲の話」だと捉えるんじゃないかなぁ. すなわち,BAになってる回答に書かれているような「赤の他人が使う可能性のあるコードを書いているような状況」のことではなくて,例えば「サイズ64を前提としてよい/処理対象の配列自体,特定のものとしてよい」ようなコードを書いている場面に関する話あろう,と.
guest

回答4

0

どの書き方が一番いいですか?

"関数funcになにを求めるか"による。

「処理したい配列はbuffのみ、サイズは64固定」が前提なら、引数のない(2)が楽。
「どんな配列でも処理したい、サイズは64固定」なら(1)
「どんな配列でも/どんなサイズでも処理したい」という要求があるなら(3)一択。
※ ...自明ではないか?

配列の受け渡しは下記の方法以外にありますか?

「引数で渡す」(1)(3) か 「呼び/呼ばれの双方が参照可能なグローバル変数を用意する」(2)
の二つ以外思いつかない。

コード2で宣言しているグローバル変数bufについてstaticを付けるべき場面が分かりません。

他の ~.c から参照(読み書き)してほしくないとき。
~.c がひとつしかない本件では意味を持たない。

投稿2022/10/15 06:05

編集2022/10/15 06:08
episteme

総合スコア16614

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

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

0

処理対象たる配列のサイズ(要素数)が固定で良い場面においては,そのサイズの配列を構造体で包むという手がある.

C

1//用途に応じた適切な名前を付けた 2//こういう型を用意すればいいよね,っていう話. 3typedef struct XXXData{ char Buff[64]; } XXXData;

利点(と思う事柄):

  • 関数仕様が極めて明確になる.「サイズ64の配列だけを扱う前提のコードなんだけど,うっかり違うサイズの配列が指定されたらどうしよう…」みたいなバッファサイズに関する不安がなくなる.(「他人」が実装に関わってきても,素の配列と比べるとその点の安心感がある)
  • 構造体同士のコピーで配列内容のコピーができる点が場合によっては便利(素の配列だとちょっと面倒だよね).

欠点(〃):

  • とにかく毎度この構造体を扱う形で書かないとならないという縛りは発生する(もちろんそれこそが狙いであり利点なのだが).これは状況次第ではちょっと面倒である.例えば,長い配列の中のサイズ64な一部分を処理対象にするようなことが多発する場面には向いていない.

投稿2022/10/17 01:39

fana

総合スコア11654

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

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

0

ベストアンサー

(2)は基本的に論外。例外として競技プログラミングみたいな場合のみ。
(2)はグローバル変数といって使い方を誤るとバグの温床になりやすい。
しかもデバッグも相当面倒になる。
参考: 【C言語】なぜグローバル変数は使わない方が良いのか?

(1)と(3)は処理内容次第だと思います。

個人的には(3)がベターだと思っています。
(1)だと、たとえばこの関数がもしWindows APIなりQtなり.NET Frameworkなりのような外部ライブラリ状態で提供されている場合は、利用者は(関数の)作成者以外です。そうなると要素数が違うものに入れようとする可能性だってありますね。
たとえば引数としては char data[10] の配列を渡しているのに戻り値はchar res[3] みたいな感じで引き受けようとする可能性だってあります。
なので引数を戻り値扱いにして処理する方が楽なのではと思いますね。

投稿2022/10/15 09:31

編集2022/10/15 09:36
BeatStar

総合スコア4958

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

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

karasuma

2022/10/15 10:57

多種多様な意見ありがとうございます。2で開発を進めようとしていましたが、仰る通りグローバル変数を安易に多用するのもどうかと思っていたところでしたので納得出来る意見をいただけました。
episteme

2022/10/15 12:03

問2,3はどーでもよかった ってことですか?
fana

2022/10/17 01:52 編集

> たとえば引数としては char data[10] の配列を渡しているのに戻り値はchar res[3] みたいな感じで引き受けようとする可能性だってあります。 これは具体的にどう書いた場合の話でしょうか? 文言だけから解釈すると, char* func(char * buff); っていう関数に対して,呼ぶ側が char data[10]; char res[3] = func( data ); とか書く,……という状況を思い浮かべますが… (C言語ってこんなことできるんでしたっけ?) #せっかくだから「説明が不足している」っていうやつを入れてみました.(自分が話を読めてないだけなのですが)
guest

0

補足までに質問が「どの書き方が一番使われますか?」だったら私の浅い経験上,3が一番近いように感じました.
参照可能なもの及び必要情報を渡して書き換えさせるという点で一致しています.サイズがハードコーディングされるのはあまり見ないですし.

実際の関数を挙げるならstrftime()とかstrcpy()とかに近くて良いと思います.ただvoidを返すのは勿体無くstrftime()は書き込んだサイズを返しますし,strcpy()は第一引数そのまま返したりしています.

投稿2022/10/15 07:10

PondVillege

総合スコア1579

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問