C++で配列を返すにはどのようにしたらよろしいのでしょうか。
いろんなことを一応やってみましたが先頭の配列しか受け取ることができません。
また、受け取り方もよく分かってないのでその辺もお願いします。

このQ&Aに関連する最新のQ&A

A 回答 (8件)

もうひとつ



まず、CやC++の世界では、
関数の引数として配列を渡すような
表記は、単に、ポインタを渡してい
るだけなので、引数として指定した
場合には、受け渡しだけでは、要素
毎のコピーは発生しません。

たとえば、
http://www.kouno.jp/home/c_faq/c6.html#4
にある、「 なぜなら配列が渡された
ときに、関数が実際に受け取るのはポ
インター であるからである」



さて、それだけではなんなので、
単純にポインタを引数とせずに配列
を渡す形にした方がわかりやすい例
です。

関数の引数に配列表現を使うのは、
多次元(実際には配列の配列)を
使うときにわかりやすくなるという
効果があります。

たとえば

int color[1024][768];

というような配列を渡したいとき、
ポインタとしてやりくりするより、
シンプルに

void revers(int color[1024][768]);

のように渡して、関数内で配列として
取り扱う方がわかりやすいと思います。

ただ、厳密に言えば、

・Cには多次元配列はない
 (あるのは、配列の配列の……)
・関数の引数で書いた配列の
 要素数は無視される

というのがあって、一番内側の
数字は無視されます。

ですので、
void revers(int color[][768]);

でも同じです。
ただし、

void revers(int color[][]);
void revers(int color[1024][]);
はエラーになります。

また、たとえ、

void revers(int color[1024][768]);

と書いても、実際の配列の要素数は
チェックされませんので、注意が必要
です。

多次元配列はないという意味は、実は
int color[1024][768];
は、

・int [768] という配列の型があって
・それが、[1024] 個ある配列

という意味になります。

ですから、
void revers(int color[][768]);
の内側の [] は、配列の要素数なので
無視される(なくても良い)
外側の [678] は、int [768] という
型の一部なので、省略不可
ということになります。
    • good
    • 1

初心者とのことなので、理解できる可能性は低いですが...



結果を格納する配列を引数として渡す場合、一般的には強い例外安全保障ができなくなります。配列の要素のコピーコンストラクタが決して失敗しないか、決して失敗しないswapが用意されている場合だけ、強い例外安全保障が可能になります。その場合でも、正しく実装するには相応の知識が必要です。

具体的には、

void func(std::string array[10])
{
 std::string temp[10] = { ... };
 for (int i = 0; i < 10; i++)
  array[i].swap(temp[i]);
}

のようにしなければなりません。
つまり、関数内部で一通りのコピーが必ず発生します。
    • good
    • 0

再度補足です。



引数で配列を受け渡しする方法がわかりに
くいので。

関数の仮引数の形で、配列を指定する
表現方法があります。

void func(int a[]);

のようにすれば、この引数は、int の
配列であることを明示できます。

具体的な処理としても

void func(int a[])
{
int x = a[10];
// 呼び出したり、

a[11] = x + 1;
// 代入したり
}

できます。
このとき、引数を経由した操作は、
呼び出し側に反映されます(後述)

また、配列のサイズは直接渡されま
せんので、上記の場合、a[10] や、
a[11] が存在しなくてもコンパイラは
何も言いません。
(実行時に良くないことが起こるで
しょう)

この関数を呼び出すときには、配列名を
引数にできます。

main()
{
int x[100];

func(x);

のように
}

ただ、この場合は、本当は、配列を
引き渡しているのではなく、配列の
先頭を指すポインタを渡しているだ
けです。

ですので、

void func(int a[]);
は、
void func(int *a);
と同じだと考えて差し支えありません。

実際には、このように、アドレスを
渡しているので、関数側の操作が
呼び出し側に反映されてしまうわけで
す。
    • good
    • 0

補足です。


ANSI 以降のCでは、「構造体を返す」のは、
値をコピーするので処理コストがかかるとい
う以上の問題はありません。

処理スピードを問題にしなければ、返せる
値のサイズにも上限はありません。

「構造体を返す」場合は、単に、値のコピー
が発生するだけですから、メモリをどう確保
するかは、処理系にお任せすれば良いことに
なっています。

ただ、普通は、関数の返値として返すのでは
なく、引数として渡すことが多いですね。

int a[100];
に対して、

void func(a[])
{ ..... }

という関数に、

func(a);

と渡せば、関数内で、配列 a を操作できます。


あえて、(構造体経由で)配列を「返す」なら
たとえば、

a.h
-------
struct array_type
{
int a[1024];
};

array_type func(int v);
-------

a.cpp
------
#include "a.h"

array_type func(int v)
{
array_type wk;

for (int i = 0; i < 1024: i++)
wk.a[i] = v;

return wk;
}
------

b.cpp
------
#include "a.h"

int main()
{
arrya_type value;
value = func(3.14);
// ここで、値のコピーが発生する

// いろいろな処理
// value.a[i] などで、配列としては機能する
// でも、本当は、構造体
}
------

これで、あえて、メモリを明示的に確保すること
も、メモリリークを起こすこともなく、実行は
できます。

ただ、後で読む人が、「なぜここで構造体?」
と悩むことにはなると思います。

C++では、(明示的に定義してあれば)コピー
コンストラクタというのがあって、これが悪さを
するとか、これがないために、「単なる値のコピー」
が発生するとか、そういう話題はありますが、
普通に構造体を返すのは、上述のような、大きな
データのコピーという問題があるだけです。
    • good
    • 0

ネイティブコードはプリミティブな値(Max64ビット)しか返せません。


オブジェクト型を返す場合でも関数からの戻り値はポインタで、本体は
別のメモリ空間にあります。
そもそも、C言語では配列の次元、要素数の管理は利用者の責任で
行うことになっています。つまり、「配列の先頭だけ渡すから、あとは
勝手にやってくれ」なのです。故に、要素数を5個しか定義していない
配列に対し、インデックスが6でアクセスしてもエラーになりません。

個人的な意見ですが、C、C++で配列や構造体を戻り値の型にするのは
プログラムの効率的な作り方から見れば、「やってはいけない」の
代表格みたいなものです。

先ず、次のことを考えてみてください。
★呼び出されたメソッドが返す配列は何処に作られたものか?
 自動変数であれば、メソッドから返った時に解放されてしまい、
 内容は不定になります。また、メソッド内でアロケートしたもの
 であるなら、メモリを解放する責任は誰にあるのか?
★それでも、明示的にアロケートしているなら百歩譲って良しと
 しましょう。しかし、単に構造体なりを返すと、先に述べたように
 戻り値を保存しておくメモリを確保する内部コードが生成される
 ことがあります。(実際にそうなるケースが多い)
 すると、ソースコード上では見えないメモリを消費しますし、誰も
 解放しないので、繰り返し実行するとメモリストレスになります。

よって、配列や構造体を返す場合は呼び出し側が領域を確保して、
そのポインタを渡し、呼び出されたメソッドはそこに結果を記録
するべきだと思います。

この回答への補足

C++を学び始めて1ヶ月もたっていないのでよく分かりません。
やりたいことはa.cppとb.cppでbで作った配列をaで受け取れるようにしたいのですがどのようにしていいか分からず困っています。
よろしくお願いします。

補足日時:2009/05/27 11:17
    • good
    • 0

配列全体を直接返す方法はありません。


ただ、構造体は直接返すことができます。
これを応用すると、配列をメンバーにし
た構造体を返すことで、実質的に配列を
返すという手もあります。

同じく、配列は直接代入できないのでが、
構造体は直接代入できるので、配列をメ
ンバーとする構造体経由で、配列を代入
したりもできます。
    • good
    • 0

通常は ポインタを渡すしかないんじゃないのかな



古い考えなら呼び元で領域確保して処理側へ確保できたポインタを渡して終ったら確保された値を順に使う・・・
今は色々やり方は有るだろうけど大きくは変ってない筈・・・
    • good
    • 0

配列を直接返す方法はありません。


お勧めなのは、

std::auto_ptr< std::vector<int> > func();

のように、vectorをauto_ptrにして返す方法です。
auto_ptrにしておかないとvector全体のコピーが発生するため、効率が低下するとともに、例外が送出するリスクも発生します。
    • good
    • 0

このQ&Aに関連する人気のQ&A

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

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

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

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

Q英語配列のキーボードのメリットは?

ブログやホームページ上で、英語配列のキーボードを勧める記事を時々見かけます。それらの記事によると、特にプログラマーにとっては、英語配列のキーボードの方が便利と書いてあるのですが、実際のところはどうなのでしょうか?
英語配列のキーボードと、日本語配列のキーボード、両方使ったことがある人にお聞きしたいのですが、どちらの方が使いやすかったですか?プログラマーの方は、実際に、英語配列のキーボードの方が打ちやすくなったのでしょうか?是非、意見をきかせてください。

Aベストアンサー

若いころはキーボードの配列に凝ったこともありました(無理やりキーバインドをカスタマイズして古くから慣れ親しんでいたPC88と同じキー配列にしてみたこともあります)。その様なバカなことを繰り返していた中で得た結論は、要は慣れです。

私は好んで英語配列のキーボードを使っていますが、日本語配列キーボードで困ったことはスペースバーが短いことだけで、それ以外は特にどちらが優れているとか思いません。もちろん今現在は日本語配列キーボードを触ると幾分タイピングは遅くなりますが、それは単純に今の私の手が英語配列キーボードに慣れているだけで、日本語配列キーボードに慣れればそちらの方が使いやすいと感じると思います。

Q[C++/CLI]マネージコードで配列を作成してネイティブコードの配列にコピーしたい

Visual C++ 2005のC++/CLIでプログラム作成しています。
C言語で書かれたプログラムを組み込みたい為に、
マネージコードでテキストファイル読み込みをして、2次元配列に格納し、
int型に変換してネイティブコードの配列にコピーしたいのですが、上手く書けません。。
テキスト内容は数字のみで2次元に並んでおり、1文字ずつ配列に入れたいです。
エラー出ているのですが、下記にコードを載せます。

#include<string>
#include<vcclr.h>

using namespace System;
using namespace System::IO;

int main(void){

//ファイルオープン
StreamReader^ sr = gcnew StreamReader("hoge.txt");
int x, y;

//ファイルの内容読込み
for(y=0;;y++){
String^ line = sr->ReadLine();
  //データ末尾まで読み込んだらループ終了
if(line == nullptr) break;
   array<array<String^>^>^ table = gcnew array<array<String^>^>(line->Length);
   int X=line->Length;
   int Y=table->Length;
//読み込んだ内容を表示
Console::WriteLine("<System::String表示>" + table);
   //System::Stringのline内容(文字列)をコピーする変数
  char tmp[128];
  sprintf(tmp,"%s",line);
  printf_s("<char配列> tmp=%s\n",tmp);
//char*変数の内容表示
  array<array<int>^>^ data= gcnew array<array<int>^>(Y,X);
//int型に変換
for(x=0;x<X;x++){data[y][x]=atoi(table[y][x]);}
}
//ファイルのクローズ
sr->Close();
  
  return 0;
}

汚く読みづらいコードで大変申し訳ありません。。
元はdefineで成分数(X,Y)を宣言していました。
しかし、読み込むファイル内容によって変えたく、arrayでLengthを使いました。
またこれ以外でいい方法がございましたら、どうか教えてください。
どなたか、ご教授よろしくお願いします。

Visual C++ 2005のC++/CLIでプログラム作成しています。
C言語で書かれたプログラムを組み込みたい為に、
マネージコードでテキストファイル読み込みをして、2次元配列に格納し、
int型に変換してネイティブコードの配列にコピーしたいのですが、上手く書けません。。
テキスト内容は数字のみで2次元に並んでおり、1文字ずつ配列に入れたいです。
エラー出ているのですが、下記にコードを載せます。

#include<string>
#include<vcclr.h>

using namespace System;
using namespace System::IO;

in...続きを読む

Aベストアンサー

 こんばんは。補足を頂きました。

 合点が行きました。ファイルによってXとYが可変するという事は、少なくともdata[y][x]は動的に割り当てないと対応できないのでは。
 なるべくString^やarray<T>^を利用して、寸前までC言語への変換を遅らせた方が良いかもしれません。

 array<array<String^>^>^ table

 とされていますが、実際には

 array<String^>^ table

 で十分だと思います。ストリームリーダへ1ライン毎に読み込ませながら、tableを拡大して行けば良いと思います。

 y = table->Length
 x = line->Length

 を使って、int data[y][x]を動的に割り当てて、

 data[y][x] = int::Parse(table[y][x].ToString())

 としていけば、atoi()を使用せずとも簡単に変換出来ます。
 複雑化して来ているので、なるべくフェーズ毎に関数へ分解した方が最終的には取り扱いが楽になります。
 後、ループはfor each in構文を使用した方が、良い事もあります。
 以下参考程度です。

 因みに此れ、例えば、
 2547379780
 6972206030111
 7920373017
 2
 11
 657

 などでも受け付けます。array<T>^やString^を使用しているので、そう言った事が簡単に出来ます。
 もしかしたら、間違いがあるかもしれませんが、そこはご勘弁です。

#include<string.h>
#include<vcclr.h>
#include<stdlib.h>

using namespace System;
using namespace System::IO;

//2次元配列のハンドル
struct Array2DHandle
{
int width;//Xの事
int height;//Yの事
int** data;//data[y][x]で使用する
};
//2次元配列を割り当てる
void AllocateArray2D(Array2DHandle* handle)
{
//縦幅を割り当てる
handle->data = new int*[handle->height];

//横幅を割り当てる
for(int y = 0; y < handle->height; ++y)
{
handle->data[y] = new int[handle->width];
}
}
//2次元配列を開放する
void Array2DFree(Array2DHandle* handle)
{
//横幅を開放する
for(int y = 0; y < handle->height; ++y)
{
delete [] handle->data[y];
handle->data[y] = NULL;
}

//縦幅を開放する
delete [] handle->data;
handle->data = NULL;
}
//String^テーブルからint[y][x]に変換する
void ConvertArray2DFrom(Array2DHandle* handle, array<String^>^% table)
{
int y = 0;
for each(String^ line in table)
{
printf("<int配列> ");
int x = 0;
for each(Char wc in line)
{
handle->data[y][x] = int::Parse(wc.ToString());
printf("%d", handle->data[y][x]);
++x;
}
printf("\n");
++y;
}
}
//ストリームリーダーを読み込んで、String^テーブルを作成する
array<String^>^ ConvertTableFrom(StreamReader^% sr)
{
array<String^>^ table = gcnew array<String^>(0);
String^ line = nullptr;
while(!sr->EndOfStream)
{
line = sr->ReadLine();

//読み込んだ内容を表示
Console::WriteLine("<System::String表示>" + line);

//String^テーブルを拡大して読み込んだ内容を入れていく
table->Resize(table, table->Length + 1);
table[table->Length - 1] = line;
}
return table;
}
//String^テーブルの最大横幅を調べる
int GetTableMaxWidth(array<String^>^% table)
{
int width = 0;
for each(String^ line in table)
{
//比較しながら一番文字数が多かったString^がdata[y][x]のxに必要な幅
if(width > line->Length)
continue;

width = line->Length;
}
return width;
}

int main(void)
{
//ファイルオープン
StreamReader^ sr = gcnew StreamReader("hoge.txt");

//ファイルが無い
if(sr == nullptr)
return 0;

//String^の配列に変換する
array<String^>^ table = ConvertTableFrom(sr);

//ファイルのクローズ
sr->Close();

//配列が拡張されなかった
if(table->Length == 0)
return 0;

//2次元配列の作成準備
//サイズ固定={X, Y}で入力する
//Array2DHandle handle = {10, 3};

//こっちは、読み込んだ文字列の行数と一番大きな文字列数からdata[y][x]のyとxを決定する
Array2DHandle handle = {GetTableMaxWidth(table), table->Length};

//割り当てる
AllocateArray2D(&handle);

//String^の配列からint[y][x]に変換する
ConvertArray2DFrom(&handle, table);

//開放する
Array2DFree(&handle);

return 0;
}

 こんばんは。補足を頂きました。

 合点が行きました。ファイルによってXとYが可変するという事は、少なくともdata[y][x]は動的に割り当てないと対応できないのでは。
 なるべくString^やarray<T>^を利用して、寸前までC言語への変換を遅らせた方が良いかもしれません。

 array<array<String^>^>^ table

 とされていますが、実際には

 array<String^>^ table

 で十分だと思います。ストリームリーダへ1ライン毎に読み込ませながら、tableを拡大して行けば良いと思います。

 y = table-...続きを読む

Q教えてください! 東プレのキーボード、英語配列104キー購入しましたが、パソコンに繋いでもJIS配列

教えてください!
東プレのキーボード、英語配列104キー購入しましたが、パソコンに繋いでもJIS配列と認識しています。
英語配列と認識しても、アルト+チルトで日本語にできません。英語配列と認識させながらローマ字入力するにはどのように設定すればいいですか?
ご指導お願いします。

Aベストアンサー

参考に
https://support.microsoft.com/ja-jp/kb/416037
日本語だから、これと同じようにして、英語にすればよいってことになります。
レジストリなら、英語だから、kbd101.dllにして、PCAT_101KEYですけどね

http://qiita.com/shimizu14/items/000cceb9e72a492b9176
http://blog.heiichi.com/?eid=792239

QC++配列の型に関するC++規格について教えていただきたいです。

C++配列の型に関するC++規格について教えていただきたいです。

以前にYahoo知恵袋でも質問しましたが、答えが得られませんでしたので、こちらでも質問させていただきたいと思います。


※以下、質問になります。(分かり難いかも知れませんが宜しくお願い致します。)


環境は、Visual Studio 2010 (C++) です。

std::fill_n() で次のような警告がでましたので、調べていましたところ、
...\xutility(2801): warning C4996: 'std::_Fill_n': Function call with parameters that may be unsafe - ...

次のような定義方法を見つけました、
typedef char (&std::tr1::_No)[1];
↑このような定義方法があることを初めて知りました。

ちなみに、std::fill_n() は次のようになりました。
long data[32];
std::fill_n(data, 32, 0); ←正常

long* p_data = data;
std::fill_n(p_data, 32, 0); ←warning

long (&a_data)[32] = data;
std::fill_n(a_data, 32, 0); ←正常


知りたいのは、配列を関数に渡すときに、
通常は、void func(long* pd); のようにポインタで渡すと思います。
また、void func(long pd[]); や void func(long pd[32]);
もポインタの場合と同じになりますが、型保証がありません。
これはC++規格で規定されていることだと思います。

次のようにすると、型保証がされますが、この記法がC++の規格として規定されているかを知りたいです。
1. void func(long (&ad)[32]); // 関数呼び出しは、func(data);
2. void func(long (*pd)[32]); // 関数呼び出しは、func(&data);

また、通常のポインタで配列を渡すことを、配列の参照渡し?と言うと思いますが、
この1,2,は何渡し?と言われるのでしょうか?


#長い文になって申し訳ありませんが、宜しくお願い致します。

C++配列の型に関するC++規格について教えていただきたいです。

以前にYahoo知恵袋でも質問しましたが、答えが得られませんでしたので、こちらでも質問させていただきたいと思います。


※以下、質問になります。(分かり難いかも知れませんが宜しくお願い致します。)


環境は、Visual Studio 2010 (C++) です。

std::fill_n() で次のような警告がでましたので、調べていましたところ、
...\xutility(2801): warning C4996: 'std::_Fill_n': Function call with parameters that may be unsafe - ...

次のよう...続きを読む

Aベストアンサー

> 次のようにすると、型保証がされますが、この記法がC++の規格として規定されているかを知りたいです。
> 1. void func(long (&ad)[32]); // 関数呼び出しは、func(data);
> 2. void func(long (*pd)[32]); // 関数呼び出しは、func(&data);

規定されています。

> また、通常のポインタで配列を渡すことを、配列の参照渡し?と言うと思いますが、

それは便宜的な表現です。
言語仕様上はあくまでも値渡しです。

> この1,2,は何渡し?と言われるのでしょうか?

1.は参照渡しですが、2.は(ポインタの)値渡しです。

Q日本語配列のキーボードと英語配列のキーボード

日本語配列のキーボードと英語配列のキーボードの
違いは何なのでしょうか?

Aベストアンサー

IBM-PC互換機なら
・キーに日本語が刻印されている
・日本語を扱うためのキー(全角/半角、変換、無変換)がある

QVC++windowsフォームプログラムでデザイナがエラーにならずにコントローラを配列に変更し、イベントも配列にする方法

VC++のwindowsFormで、ボタンやテキストボックスなどのコントローラを配列にする方法について教えてください。
先日、コントローラを配列にする方法の質問をして、ご回答頂いてその質問は締め切りましたが、新たな問題があったため、質問いたします。

先日頂いた回答では、
array<Button^>^ button = gcnew array<Button^>(2);
と、定義を配列にするため、デザイナで作成したソースに手を加えることになり、デザイナが表示できなくなってしまいました。そこで、デザイナでボタンなどを配置し、定義などは変更せずに、コントローラ配列として持つ良い方法があれば教えて頂けますでしょうか。

ボタンが50ほどあるプログラムを考えており、それぞれのボタンは独立ではないため、配列での処理が望ましいのです。また、その場合、イベントも配列にすることは可能でしょうか?可能であれば併せてご教授願います。

Aベストアンサー

FormのLoadイベントはデザイン画面を表示して、Form1を選択中にしてプロパティウィンドウ(初期は右側に出ると思う)
のイベント(雷マーク)のLoadイベントにForm1_Loadと記入すればコードが自動的に挿入されます。

ちなみにbutton1、button2、、、というオブジェクト名であれば、

this->buttons = gcnew Generic::List<Button^>();
for (int i = 1; i <= 5; ++i)
{
  Button^ btn = static_cast<Button^>(this->Controls[L"button" + i.ToString()]);
  this->buttons->Add(btn);
  btn->Click += gcnew System::EventHandler(this, &Form1::buttons_Click);
}

という記述もできます。
(パネル等のコンテナを使っているともう一工夫必要だが)

一応参考
http://hpcgi1.nifty.com/MADIA/Vcbbs/wwwlng.cgi?print+200703/07030007.txt

FormのLoadイベントはデザイン画面を表示して、Form1を選択中にしてプロパティウィンドウ(初期は右側に出ると思う)
のイベント(雷マーク)のLoadイベントにForm1_Loadと記入すればコードが自動的に挿入されます。

ちなみにbutton1、button2、、、というオブジェクト名であれば、

this->buttons = gcnew Generic::List<Button^>();
for (int i = 1; i <= 5; ++i)
{
  Button^ btn = static_cast<Button^>(this->Controls[L"button" + i.ToString()]);
  this->buttons->Add(btn);
  btn->Click +=...続きを読む

Q英語キーボード配列への設定?

USBの英語キーボードを使うことにしましたが、配列がうまく設定できません。MS-IMEのキーボード設定でUSを追加して、USモードに切り替えると、配列は一致するのですが、Alt+「`」で日本語入力モードに切り替わりません。
キー配列を一時的に変更すれば日本語入力可能ですが、日本語入力中でも記号などの配列が違うため結局解決になってません。
MSサイト http://support.microsoft.com/default.aspx?scid=kb;ja;839391 を見ると、英語キーボードのドライバをインストールすればよいようですが、手順どおりに実施してもドライバの選択画面で選択できるのは「HIDキーボードデバイス」のみです。
解決方法についてアドバイスをお願いします。

Aベストアンサー

下記サイトが参考になるかなぁ・・・・
http://www.diatec.co.jp/support/wxp-101usbsetup.html

Q先頭0で重複のない配列を作りたい

重複なく4つの領域を持つ配列に数字を代入したい(先頭は0以外の
数字)と思って書いたプログラムです。

しかし、コンパイルしてみると重複が発生してしまいます。
これはなぜ発生してしまうのでしょうか?
よろしくお願いします。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main(void)
{

int num,val,i,j;
int comp[4];

srand(time(NULL));
puts("4桁の数字を記憶して逆向きに入力しましょう。");

val=rand()%10;
do{
comp[0]=val;
}while(comp[0]==0);

for(i=1;i<4;i++)
{
do{
val=rand()%10;
for(j=0;j<i;j++)
{
if(comp[j]==val)
{
break;
}
}
}while(i<j);
comp[i]=val;
}

for(i=0;i<4;i++)
{
printf("%d",comp[i]);
}

return 0;
}

重複なく4つの領域を持つ配列に数字を代入したい(先頭は0以外の
数字)と思って書いたプログラムです。

しかし、コンパイルしてみると重複が発生してしまいます。
これはなぜ発生してしまうのでしょうか?
よろしくお願いします。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main(void)
{

int num,val,i,j;
int comp[4];

srand(time(NULL));
puts("4桁の数字を記憶して逆向きに入力しましょう。");

val=rand()%10;
do{
comp[0]=val;
}while(comp[0]==0);

for(i...続きを読む

Aベストアンサー

まず、このプログラムで本当に結果が出力できたんでしょうか?
気づいた点で・・・

>val=rand()%10;
>do{
>comp[0]=val;
>}while(comp[0]==0);

これってvalが0だったら無限ループになりませんか?
あと、

>do{
>val=rand()%10;
>for(j=0;j<i;j++)
>{
>if(comp[j]==val)
>{
>break;
>}
>}
>}while(i<j);

これも無限ループになりませんか?

Q英語OSと日本語OSでキーボード配列が違う理由

なぜ違うのですか?
また、英語OSで日本語OSと同様のキーボード配列にする方法を教えてください。

Aベストアンサー

それは、JISでキー配列を決めた人に文句を言ってください、としか言いようがない話ですね・・・カナ配列も戦前からの歴史があったカナタイプ配列を捨てて、がらっと違うものにしてしまっている上に、記号類の並びも英語キーボードとは異なるなどの理由から、JIS配列に批判的意見があったことは事実です。これだけ広まってしまった後に文句を言っても、どうしようもないんですけど。

英語OSでも日本語キーボードを接続して使うことは可能なので、次のリンクを見てください。

マイクロソフト公式情報(ただしXPまで)
http://support.microsoft.com/kb/831774/ja

Vistaでの変え方
http://www.runexyfaq.com/parallels/pd-post55.html

ともあれ、今の日本語キーボードが英語キーボードと決定的に違うのは、文字キーが二個多いということです。右側シフトキーの左隣にある「ろ」と、エンターキーの左隣にある「む」は、英語キーボードではそれぞれシフトキーとエンターキーの一部になっています。英語キーボードのエンターが大きいと感じるのはこのためです。言い換えると、英語キーボードのままで配列を日本語に変えると、この二個は打てなくなってしまいますし、変換キーや全角半角キーもなく、記号類はキートップの印刷と実際が異なるなど、不都合が多すぎます。

XP以降のOSなら、多言語対応できるので、英語版で日本語を表示したり、漢字変換を行うことは可能です。フォントとかがインストールされていない場合はインストールCDを要求されるかも知れませんけど、設定はできますよ。まあ、キー配列に慣れる必要があることには変わりないですが。

XPの場合の例
http://homepage3.nifty.com/~nekomata/ie6appcompattest/JapaneselanguageonEnglishXP-1.htm

Vista Homeの例
http://nihongopc.us/faq/2007/07/windows-vista-home.html

それは、JISでキー配列を決めた人に文句を言ってください、としか言いようがない話ですね・・・カナ配列も戦前からの歴史があったカナタイプ配列を捨てて、がらっと違うものにしてしまっている上に、記号類の並びも英語キーボードとは異なるなどの理由から、JIS配列に批判的意見があったことは事実です。これだけ広まってしまった後に文句を言っても、どうしようもないんですけど。

英語OSでも日本語キーボードを接続して使うことは可能なので、次のリンクを見てください。

マイクロソフト公式情報(ただしX...続きを読む

Q配列のポインタ配列のポインタから元の配列を参照する方法について

C初心者です。下記の様に配列のポインタ配列を作って、そのポインタ配列のポインタを返すコードを書いて、main関数で元の配列の値を参照したいのですが、上手く参照できずに困っています。下記のコードの問題点も含めて、配列のポインタ配列のポインタから、元の配列の値を参照する方法を教えてください。お願い致します。

short int *motion_data(void)
{
short int data1[5][7] = {
{2377,2174,0,0,0,0,0},
{2377,2377,2784,2648,2648,2648,2377},
{2377,2377,2784,2648,2648,2648,2377},
{2377,2377,2377,2377,2377,0,0},
{2377,2377,2377,2377,2377,0,0},
};
short int data2[5][7] = {
{2377,2174,0,0,0,0,0},
{2377,2377,2919,2784,2784,2784,2377},
{2377,2377,2919,2784,2784,2784,2377},
{2377,2377,2377,2377,2377,0,0},
{2377,2377,2377,2377,2377,0,0},
};

short int *po_data[2];

po_data[0] = data1[0];
po_data[1] = data2[0];

return *po_data;
}

C初心者です。下記の様に配列のポインタ配列を作って、そのポインタ配列のポインタを返すコードを書いて、main関数で元の配列の値を参照したいのですが、上手く参照できずに困っています。下記のコードの問題点も含めて、配列のポインタ配列のポインタから、元の配列の値を参照する方法を教えてください。お願い致します。

short int *motion_data(void)
{
short int data1[5][7] = {
{2377,2174,0,0,0,0,0},
{2377,2377,2784,2648,2648,2648,2377},
{2377,2377,2784,2648,2648,2648,2377},
{2377,2377,2...続きを読む

Aベストアンサー

>元の配列の値を参照する方法を教えてください。

 下のようにすると「元の配列の値を参照」できました。
  (BorlandC++5.5.1)

 No.3 さんの言われるように、
 
>関数を抜けると変数自体無くなってしまいます

 「中身自体」は、その番地をいじくらない限り、「ずっと」残っていてくれればいいんだけど・・。
 やっぱ、static かな。

#include <stdio.h>

short **motion_data( void )
{
 short data1[ 5 ][ 7 ] = {
  { 100, 101, 102, 103, 104, 105, 106 },
  { 110, 111, 112, 113, 114, 115, 116 },
  { 120, 121, 122, 123, 124, 125, 126 },
  { 130, 131, 132, 133, 134, 135, 136 },
  { 140, 141, 142, 143, 144, 145, 146 }
 };
 short data2[ 5 ][ 7 ] = {
  { 200, 201, 202, 203, 204, 205, 206 },
  { 210, 211, 212, 213, 214, 215, 216 },
  { 220, 221, 222, 223, 224, 225, 226 },
  { 230, 231, 232, 233, 234, 235, 236 },
  { 240, 241, 242, 243, 244, 245, 246 }
 };
 short *po_data[ 2 ];

 po_data[ 0 ] = &data1[ 0 ][ 0 ]; // もち = data1[ 0 ]; でも
 po_data[ 1 ] = &data2[ 0 ][ 0 ];

 return( &po_data[ 0 ] );
}
void main( void )
{
 short **po_data, *p1, *p2;

 po_data = motion_data();

 p1 = po_data[ 0 ] + 13; // 任意の「元の配列の値を参照」
 p2 = po_data[ 1 ] + 34; //   〃

 printf( "%d\n", *p1 );
 printf( "%d\n", *p2 );
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。

>元の配列の値を参照する方法を教えてください。

 下のようにすると「元の配列の値を参照」できました。
  (BorlandC++5.5.1)

 No.3 さんの言われるように、
 
>関数を抜けると変数自体無くなってしまいます

 「中身自体」は、その番地をいじくらない限り、「ずっと」残っていてくれればいいんだけど・・。
 やっぱ、static かな。

#include <stdio.h>

short **motion_data( void )
{
 short data1[ 5 ][ 7 ] = {
  { 100, 101, 102, 103, 104, 105, 106 },
  { 110, 111,...続きを読む


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

人気Q&Aランキング