ひとつの関数で、出力を配列のように複数させたいのですが、できないでしょうか。

A 回答 (4件)

戻り値では1つの値しか返せないので、引数に配列のポインタを渡し、関数内で値をセットするという方法を取ります。



int main(void)
{
  int i, array[10];
  func(array);      /* 配列のアドレスを渡す */
  for (i = 0; i < 10; i++)
    printf("%d:%d\n", i, array[ i ]);
  return 0;
}

void func(int p[ ])    /* pは配列のアドレスを受け取るポインタ */
{
  int i;
  for (i = 0; i < 10; i++)
    p[ i ] = i * i;   /* 適当に値をセット */
}

必要な宣言等は、適宜行って下さい。
配列を受け取るポインタの宣言には人それぞれ好みがあるのですが、私は「単なる変数のアドレスを受け取るのではない」ということを主張している、この方法を取っています。

ちなみに「構造体なら返せる」と言って、配列メンバを持った構造体を返してる人を見たことがありますが、できたとしてもこんな方法はやめましょう。
    • good
    • 1
この回答へのお礼

ありがとうございます。
ところで、厚かましい質問かも知れませんが、私はいつも

double f(double x)
{
double out_put;
out_put = x * x;
return(out_put);
}

という関数で、

y = f(x);

のようにしてyに出力させています。
この形が慣れ親しんでいるのですが、このような形で複数の出力はできないでしょうか。
あと、お時間があれば、もうひとつお願いします。
私はいつも、mainを

void main(void)

としているのですが、これらのvoidとはどういう意味なのでしょうか。
よろしくお願いします。

お礼日時:2001/09/20 20:26

No.3の方のソースを元にしてみました。



struct int_array {
int size;
int *pi;
};

struct int_array *func()
{
struct int_array *p = (struct int_array *)malloc(sizeof(struct int_array));
int *pil = (int*)malloc(sizeof(int[2]));
pil[0] = 10;
pil[1] = 20;

p->pi = pil;
p->size = 2;
return p;
}

int main(void)
{
struct int_array *p = func();

/* 処理 */

free(p->pi);
free(p);

return 0;
}

こんな感じでどうでしょうか。

C++ならば、struct int_arrayはクラスにしてデストラクタで領域を解放させるべきですが。
(さらに言えばSTLやクラスライブラリを使ったっていいんですけどね)
    • good
    • 0
この回答へのお礼

ありがとうございました。
うーん、わたしにはちょっと複雑です。(^^;
「->」あたりからよくわからないです…

安直にはいかないということがわかっただけでも、収穫でした。

お礼日時:2001/09/22 09:47

お勧めはしませんが、こんなやり方もあります。



#include <stdlib.h>
int * func()
{
 int *p;
 p = (int*)malloc(sizeof(int[2]));
 p[0] = 10;
 p[1] = 20;
}

int main(void)
{
 int *a;
 a = func();
 printf("%d, %d\n", a[0], a[1]);
 free((void*)a);
 return 0;
}

呼び出された関数の内部でメモリーを確保して、そのポインタを返しています。
一般的には、そのポインタはプログラム内で明示的に解放する必要があります。
    • good
    • 0
この回答へのお礼

ありがとうございます。(^O^)
良し悪しがわからないので、お勧めしないなら、あまり使ってみる気がしないです…(^^;

ともかくありがとうございました。

お礼日時:2001/09/22 09:43

> y = f(x);


の形で複数の値を返すことはできません。返したい値が2つか3つ程度であれば、

int main(void)
{
  int a, b;
  func(&a, &b);
  printf("%d, %d\n", a, b);
  return 0;
}

void func(int *x, int *y)
{
  *x = 10;
  *y = 20;
}

のようにして、値をセットするのが普通です。

> void main(void)
main関数は、終了時にシステムに終了コードを返すべきなので、戻り型をint宣言するのが正しい宣言方法です。(引数はvoidでもOKです。)

で、このvoidというのは、戻り値や引数が「ない」ことを示すために使う型です。
void型自体は、関数プロトタイプくらいでしか見ることはないでしょう。(まれにvoidキャストを使うことはありますが。)
メモリ確保などを行う場合、void * というポインタ型が出てきたりもするので、参考書などで調べてみるとよいでしょう。

この回答への補足

「お礼する」で登録してしまったので、こちらに書きます。

>> y = f(x);
>の形で複数の値を返すことはできません。

そんなうまい話はないですね。(^^;
ありがとうございました。

補足日時:2001/09/22 09:36
    • good
    • 0
この回答へのお礼

ありがとうございました。
これからは
int main(void)
で行こうとおもいます。

お礼日時:2001/09/22 09:36

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

Q改行させずに文字配列を出力させる関数

改行させずに文字配列を出力させる関数は、printf以外にありますか?

printf("Hello world!!"); //改行せずに出力

char str[]="Hello world!!";
puts(str); //改行されて出力

出力の最後に自動的に改行文字を追加しないで、文字配列を表示する標準関数って、printf以外にありますか?
もしくは、改行されない関数が必要な場合は自作するしかありませんか?

Aベストアンサー

fputs(str, stdout);
fprintf でもいいけど。

Q関数ポインタ配列の関数名を検索

関数ポインタ配列に格納されている関数名を文字列で検索して
配列の番号を得たいのですが、どんな方法が考えられるでしょうか?

void (*p_func[])(char*) = {
  display,
  output,
};

int main()
{
  int fncNo;
  fncNo = serchFnc( "display" ); //このserchFnc関数を作りたい
  p_func[ fncNo ]( "abcd" );
  return 0;
}

上の例ですとdisplay関数が実行されます。
関数を50個ぐらいまで増やす予定なので追加や削除に耐えられるような
保守性のある方法が理想です。
構造体を使って関数名と検索文字列をワンセットに出来ないか考えたんですけど
適切な方法が思いつきませんでした。

Aベストアンサー

#include <stdio.h>

typedef void (*funcptr)(char*);

struct func_t {
  const char* name;
  funcptr func;
};

#define F(f) { #f, f }

void a(char* str) {
  printf("a%s\n", str);
}
void b(char* str) {
  printf("b%s\n", str);
}
void c(char* str) {
  printf("c%s\n", str);
}

funcptr searchFunc(const char* n, struct func_t* table) {
  while ( table->name != NULL ) {
   if ( strcmp(table->name, n) == 0 ) {
    return table->func;
   }
   ++table;
  }
  return NULL;
}

int main() {
  funcptr p;
  struct func_t ftable[] = {
   F(a),
   F(b),
   F(c),
   {NULL, NULL}
  };
  if ( (p = searchFunc("a",ftable)) != NULL ) (*p)("-found");
  if ( (p = searchFunc("b",ftable)) != NULL ) (*p)("-found");
  if ( (p = searchFunc("c",ftable)) != NULL ) (*p)("-found");
  if ( (p = searchFunc("d",ftable)) != NULL ) (*p)("-found");
  return 0;
}

#include <stdio.h>

typedef void (*funcptr)(char*);

struct func_t {
  const char* name;
  funcptr func;
};

#define F(f) { #f, f }

void a(char* str) {
  printf("a%s\n", str);
}
void b(char* str) {
  printf("b%s\n", str);
}
void c(char* str) {
  printf("c%s\n", str);
}

funcptr searchFunc(const char* n, struct func_t* table) {
  while ( table->name != NULL ) {
   if ( strcmp(table->name, n) == 0 ) {
    return table->func;
...続きを読む

QC言語で、他の関数で配列を書き換えられないようにしたい

下のCのプログラムでは、func関数は配列aの先頭要素へのポインタを返します。

main関数の側では配列aの中身を表示します。
しかし、main関数のfor文の中の★の部分をコメントアウトせずに入れると、この配列の中身が書き換わってしまいます。
 私はfunc関数以外では、この配列の中身をいじられたくないのです。
 なんとかfunc関数を工夫して作成して、func関数以外では、配列の中身が変わらないようにしたいのですが、どうすればよいでしょうか。
 
 とは言ったものの、多分できないだろうなあ、という気がします。
 できないならばできないでも仕方ないのですが、確信が持てないのです。

条件があります。
funcでは表示は行なわない。
配列aの中身を表示できるように、funcから呼び出し元へ、aのアドレスまたはaの先頭要素のアドレスがわかるような情報を返す。


#include <stdio.h>

char *func(int i)
{
static char a[]="AAAA";
a[i]='z';
return a;
}

int main(void)
{
int i;
for(i=0; i<4; i++)
{
char *p=func(i);
/* p[i]='X'; ★配列の中身を書き換えてしまう。 */
puts(p);
}
return 0;
}

下のCのプログラムでは、func関数は配列aの先頭要素へのポインタを返します。

main関数の側では配列aの中身を表示します。
しかし、main関数のfor文の中の★の部分をコメントアウトせずに入れると、この配列の中身が書き換わってしまいます。
 私はfunc関数以外では、この配列の中身をいじられたくないのです。
 なんとかfunc関数を工夫して作成して、func関数以外では、配列の中身が変わらないようにしたいのですが、どうすればよいでしょうか。
 
 とは言ったものの、多分できないだろうなあ、とい...続きを読む

Aベストアンサー

staticな変数を使う限りは無理な話です。

func内でnon-staticな領域にコピーしたものをreturnする。
仕様を明記し,funcを呼び出した先で別のバッファへコピーして使うよう徹底する。

などの対策をするしかないでしょう。
こういう仕様では,逆にfunc関数以外で使っていた文字列の内容が funcの呼び出しによって意図せず書き換えられてしまう,といった逆のパターンも往々にしてあります。要注意。

Q複数テキストファイルを読み込み、複数テキストファイルの出力

質問は100個のテキストファイル(それぞれ10個のデータを含む)を読み込み、それぞれのテキストファイルから5個ずつデータを抽出し、200個のテキストファイルとして出力するというプログラムについての質問です。
以下が僕の作ったファイル出力部分のプログラムです。

/************/

void ecg_rr(fp,data_max)

FILE *fp;
{
int b,i=0;
int c=1;
char fname[64];

data[0][i]=trend_data[0][i];

for(i=0;i<100;i++)

sprintf(fname,"ss[%d].txt",1+i);

fp = fopen(fname,"w");
fprintf(fp,"%4d\n",c);
fprintf(fp,"%8.8f\n",data[0][0]);
fprintf(fp,"%8.8f\n",data[0][2]);
fprintf(fp,"%8.8f\n",data[0][4]);
fprintf(fp,"%8.8f\n",data[0][6]);

fclose(fp);

sprintf(fname,"sk[%d].txt",1+i);

fp = fopen(fname,"w");
fprintf(fp,"%4d\n",c);
fprintf(fp,"%8.8f\n",data[0][1]);
fprintf(fp,"%8.8f\n",data[0][3]);
fprintf(fp,"%8.8f\n",data[0][5]);
fprintf(fp,"%8.8f\n",data[0][9]);

fclose(fp);


}

複数ファイルの読み込み方がわからず、自分のプログラムだと1つのテキストファイルしか読み込めないので、16_4.batを作り、その中身を
16_4 読み込むテキストファイル名1.txt ss[1]
16_4 読み込むテキストファイル名1.txt sk[1]

16_4 読み込むテキストファイル名2.txt ss[2]
16_4 読み込むテキストファイル名2.txt sk[2]
・・・
とやったのですが、うまくいきませんでした。
どうすればよいのでしょうか。

質問は100個のテキストファイル(それぞれ10個のデータを含む)を読み込み、それぞれのテキストファイルから5個ずつデータを抽出し、200個のテキストファイルとして出力するというプログラムについての質問です。
以下が僕の作ったファイル出力部分のプログラムです。

/************/

void ecg_rr(fp,data_max)

FILE *fp;
{
int b,i=0;
int c=1;
char fname[64];

data[0][i]=trend_data[0][i];

for(i=0;i<100;i++)

sprintf(fname,"ss[%d].txt",1+i);

...続きを読む

Aベストアンサー

>read_dataの呼び出しは上位レベルのものを直接
>sprintf(fname,,"ss[%d].txt",1+i);
>の後に代入すればよいでしょうか?
私には、上位レベルがどうなっているのかわかりませんので、判断がつきませんが、その前の方がいいと思います。
例:
for(i=0;i<100;i++)

sprintf(fname,"読み込むテキストファイル名%d.txt",i+1);
fp=fopen(fname,"r");
read_data(fp); /* リターン値を使う必要あり? */
fclose(fp);

sprintf(fname,"ss[%d].txt",1+i);

Q構造体をディスクからロードして複数バッファリングさせる

構造体をディスクからロードして複数バッファリングさせておくようなプログラムを組みたいと思い、
C言語で下のようなコードを記述しました。
※質問にあたり最小限の記述にしています。

#define SIZE (sizeof(struct hoge))
#define NUM 16

char buf[SIZE*NUM];
fd=open(file_name,O_RDONLY);
read(fd,buf,SIZE*NUM);

上のような記述(read)をして構造体(hoge)を16個分確保できてしまいました。
ここで疑問に当たりました。

(1) read(fd,buf,SIZE);
(2) read(fd,buf,SIZE*NUM);

個人的には(1)と書いても(2)のように書いて、fdが指すポインタから、SIZE分読み込んだ時点で、ファイルの末尾に達するので読み込みが終わると思っていました。
SIZE*NUM分読めたことに納得がいきません。

末尾にきたらファイルの先頭に戻っているのでしょうか?
readのmanを読んでも間違いないと思えるのですが。。

お分かりの方いらっしゃいましたらぜひぜひ教えてくださいませ。

構造体をディスクからロードして複数バッファリングさせておくようなプログラムを組みたいと思い、
C言語で下のようなコードを記述しました。
※質問にあたり最小限の記述にしています。

#define SIZE (sizeof(struct hoge))
#define NUM 16

char buf[SIZE*NUM];
fd=open(file_name,O_RDONLY);
read(fd,buf,SIZE*NUM);

上のような記述(read)をして構造体(hoge)を16個分確保できてしまいました。
ここで疑問に当たりました。

(1) read(fd,buf,SIZE);
(2) read(fd,buf,SIZE*NUM);

個人的には(1...続きを読む

Aベストアンサー

>今回/var/run/utmpから構造体を読み出したわけですが
>(エントリといういのでしょうか?)なぜ複数あるのでしょうか??

man utmp

を読む限りでは、ユーザが新たにログインすると utmp ファイルにユーザ情報が追記されていくようですね。

しかし、私の使っているシステムで /var/run/utmp を読むと、最初の 17個分は空になっています。
utmp の追加の仕方までは追っていないのでこれ以上はわかりません。

ちなみにウチは FreeBSD 6.3 で、sizeof(struct utmp) は 44バイトですね。


このQ&Aを見た人がよく見るQ&A

人気Q&Aランキング

おすすめ情報