関数プロトタイプ宣言(自作関数)の引数に、A[4][4]というような配列を入れたいのですが、コンパイル時にエラーでincompatibleといわれてしまいます。

A[0][0]からA[3][3]までを個別に引数に指定してもエラーになります。

良い方法は無いでしょうか?

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

A 回答 (5件)

下のように書けばよいと思います。



#include <stdio.h>

void func(int arr[4][4]);
void func2(int (*arr)[4]);

int main(void)
{
int array[4][4];

func(array);
func2(array);
return 0;
}

void func(int arr[4][4])
{

}

void func2(int (*arr)[4])
{

}
    • good
    • 0
この回答へのお礼

関数プロトタイプを呼び出す際の引数にも、宣言時の引数にも同じようにhairetsu[4][4]と記載するのかと思っていました。

例に書いていただいた通り、関数プロトタイプを呼び出す引数の[4][4]を消してみたらうまくいきました。

勉強になりました。ありがとうございます。

お礼日時:2009/05/26 20:33

配列の情報全体を渡したいのか、一要素の情報だけでよいのかによって解決方法は変わります。



元のコードでは、hairetsuは、hairetsu[0][0]~hairetsu[3][3]までしかありませんから、にもかかわらずhairetsu[4][4]と書けば、未定義の動作を引き起こしてしまいます。
    • good
    • 0
この回答へのお礼

関数プロトタイプを呼び出す際の引数にも、宣言時の引数にも同じようにhairetsu[4][4]と記載するのかと思っていました。

なるほど、宣言時とは違う意味になってしまうのですね・・・

勉強になりました。ありがとうございます。

お礼日時:2009/05/26 19:52

kansuA() が示されたので、B も C もということで、3つの関数を作ってみました(BorlandC++5.5.1)。



解決の糸口になればよろしいのですが・・。

注:あえて関数側の引数名は、いっしょにしています。

  実際の場面では、( main とも含め)それぞれ別の名前が間違いが少ないかと・・。

#include <stdio.h>

double kansuA( double [ 5 ][ 5 ] ); // [][ 5 ] でも
double kansuB( double [ 5 ] );   // [] でも
double kansuC( double );

int main()
{
 double result;
 double hairetsu[ 5 ][ 5 ];

 hairetsu[ 3 ][ 1 ] = 9.111;
 hairetsu[ 3 ][ 2 ] = 90.0;
 hairetsu[ 4 ][ 4 ] = -99.111;

 result = kansuA( hairetsu );  // [ 0 ][ 0 ] - [ 4 ][ 4 ] の25ケ

 printf( "A %lf\n", result );

 result = kansuB( hairetsu[ 3 ] ); // [ 3 ][ 0 ] - [ 3 ][ 4 ] の5ケ

 printf( "B %lf\n", result );

 result = kansuC( hairetsu[ 4 ][ 4 ] ); // #1「補足」と同じの1ケ

 printf( "C %lf\n", result );

 return( 0 );
}
double kansuA( double hairetsu[][ 5 ] ) // [ 5 ][ 5 ] でも
{
 return( hairetsu[ 3 ][ 1 ] + hairetsu[ 3 ][ 2 ] );
}
double kansuB( double hairetsu[] ) // [ 5 ] でも
{
 return( hairetsu[ 1 ] + hairetsu[ 9 ] ); // ★[ 9 ]注目
}
double kansuC( double hairetsu )
{
 return( hairetsu );
}
注:インデントに全角空白を用いています。コピペ後、タブに一括変換して下さい。
    • good
    • 0
この回答へのお礼

関数プロトタイプを呼び出す際の引数にも、宣言時の引数にも同じようにhairetsu[4][4]と記載するのかと思っていました。

呼び出す際は、[4][4]の部分は省略するのですね・・・

勉強になりました。ありがとうございます。

お礼日時:2009/05/26 19:53

resultA = kansuA(hairetsu[4][4]);


とかくとhairetsu[4][4]はdouble型になりますのでkansuAの引数として宣言しているdouble[4][4]と型が合わずにエラーが出ます。
resultA = kansuA(hairetsu);
と書くか、関数の仕様を
void kansuA(double foo);
とするのがよろしいかと。
    • good
    • 0
この回答へのお礼

むむむ なにやら難しいですね・・

どうも引数とか配列とか、「値を渡す」ということを理解できていないようです。。。

今回は、引数の[]を外したらうまくコンパイルできましたが、教えていただいたことをメモして後学に生かしたいと思います。

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

お礼日時:2009/05/26 20:32

具体的にどんなコードを書いたのか、補足してください。

この回答への補足

初心者でうろ覚えですが、以下のような感じです。
よろしくお願いします。
void kansuA(double hairetsu[4][4]);
void main (int argc, char**argv)
{
double resultA;
double hairetsu[4][4];
hairetsu[1][1] = 90;
hairetsu[1][2] = 0;
hairetsu[1][3] = 0;
hairetsu[2][1] = 0;
hairetsu[2][2] = 0;
hairetsu[2][3] = 0;
hairetsu[3][1] = 45;
hairetsu[3][2] = 90;
hairetsu[3][3] = 0;

resultA = kansuA(hairetsu[4][4]);
return 0;
}
---------------------------------
void kansuA(double hairetsu[4][4]){
なにかしらの処理
}

補足日時:2009/05/25 21:18
    • good
    • 0
この回答へのお礼

ご指摘の通りソースを書いたところ、皆さんから貴重な意見を頂けました。

後学に生かそうと思います。

お礼日時:2009/05/26 20:34

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

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

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

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

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

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

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

Aベストアンサー

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

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

Qa[i]とa[i+1]を入れ替えるような関数を作成するC言語の問題

以下のように配列aとそのサイズsとインデックスiを引数
にとり、a[i]とa[i+1]を入れ替えるような関数を作成する問題。

但し、この関数内で配列の外側をアクセスしないようにエラー
チェックをすること。正常に処理が終了した場合は0を返し、
そうでない場合は-1を返すようにする。

main関数では、10個分の整数を入れる配列を宣言し、
データをユーザに入力させる。
次に、ユーザに1個整数を入力させ、0からその番号まで順に
iをずらしてswap_array関数を読んだ後、配列に入っているデータを
表示させる。

・配列にデータを入力でき、交換が正しくできている
・ユーザが配列の外側を指定した場合は、エラーである旨を
表示して終了する。

取りあえずこうゆうかんじになるのですが、//の前などをどうにすればいいか分かりません。分かる方は知恵を貸してください。

int swap_array(int a[], int s, int i)
{
//a[i]番目とa[i+1]番目を入れ替え処理をする

//正しく交換できた場合はreturn(0);
//エラーが発生した場合はreturn(-1);
}
int main()
{
//サイズ10の配列の宣言
int a[10];
//ユーザに10個のデータの入力をさせる
int i;
for(i=0;i<10;i++){
scanf("%d",&a[i]);
}
//0番目から何番目まで入れ替えるかユーザに聞く: (ユーザがnと入力)
int n;
......

//繰り返し構造を使って、0番目からn番目まで隣同士を交換
for(i=0;i<=n;i++){
int v;
// swap_arrayを繰り返し呼び出すが、毎回戻り値が0であることを
        //チェックしてエラーが発生していないことを確かめる
v=swap_array(a,10,i);

// エラーが発生していたら エラーが発生したことを表示して
//break;文で繰り返し構造から外にでる。
if(v==-1) break;
}

//エラーが発生しなかった場合に、入れ替えられた配列の内容を表示
if(v!=-1){
..... 配列の内容を表示
}

return(0);

以下のように配列aとそのサイズsとインデックスiを引数
にとり、a[i]とa[i+1]を入れ替えるような関数を作成する問題。

但し、この関数内で配列の外側をアクセスしないようにエラー
チェックをすること。正常に処理が終了した場合は0を返し、
そうでない場合は-1を返すようにする。

main関数では、10個分の整数を入れる配列を宣言し、
データをユーザに入力させる。
次に、ユーザに1個整数を入力させ、0からその番号まで順に
iをずらしてswap_array関数を読んだ後、配列に入っているデータを
...続きを読む

Aベストアンサー

こんな感じではだめでしょうか…。

#include <stdio.h>

unsigned int swap_array(int a[],unsigned int size,unsigned int s)
{
unsigned int temp,i=s;
if (size<s) return s;// 要素数を返す
while (i-1) temp=a[s-i+1],a[s-i+1]=a[s-i],a[s-i--]=temp;
return 0;
}
int main()
{
int a[10];
unsigned int n,i=0,size=sizeof(a)/sizeof(unsigned int);

do{
printf("%d個目のデータ?",i+1);
scanf("%d",&a[i]);
}while(++i<size);

//do{
printf("入れ替え対照、何番目のデータ(1~%d個)?",size);
scanf("%d",&n);
//}while(n>size || !n);
//この段階で範囲制限させる時は上記2行のコメントを解除

if (i=swap_array(a,size,n)) printf("エラー>要素数%dは範囲外です\r\n",i);
else for (i=0;i<size;i++) printf("%d個目:%d\r\n",i+1,a[i]);
return 0;
}

こんな感じではだめでしょうか…。

#include <stdio.h>

unsigned int swap_array(int a[],unsigned int size,unsigned int s)
{
unsigned int temp,i=s;
if (size<s) return s;// 要素数を返す
while (i-1) temp=a[s-i+1],a[s-i+1]=a[s-i],a[s-i--]=temp;
return 0;
}
int main()
{
int a[10];
unsigned int n,i=0,size=sizeof(a)/sizeof(unsigned int);

do{
printf("%d個目のデータ?",i+1);
scanf("%d",&a[i]);
}while(++i<size);

//do{
printf("入れ替え対照、何番目のデータ(1~%d個...続きを読む

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

Qborlandでコンパイルすると、「プロトタイプ宣言のない関数 'exit' の呼び出し」という警告が出てきます。

borlandでコンパイルすると、「プロトタイプ宣言のない関数 'exit' の呼び出し」という警告が出てきます。
一応ソースの文頭には、

#include<stdio.h>

を入れているのですが、この警告を出なくするのにはどの様にしたらいいのでしょうか?

Aベストアンサー

以下を参照してください。二番目のURLは一番目のスレの続きみたいです。

参考URL:http://ybbs.admin-man.net/8500/0002/00003098.htm,http://ybbs.admin-man.net/8500/0002/00003101.htm

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

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

Aベストアンサー

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

Qポインター引数の関数でコンパイルエラーが出る。

現在ATmega88というアトメル社製のマイコンのプログラミングを行っています。コンパイラはwin_avrを使用しています。

現在void tx_test(cc1101_client * client)というcc1101_clientポインターを引数とした関数を作成したのですが、この関数内でu16 tx_fifo_set(txfifo_data * txfifo)という txfifo_dataポインターを引数とする関数を呼び出したいと思っているのですが、これをコンパイルすると

error: incompatible type for argument 1 of 'tx_fifo_set'というエラーが出力されコンパイルできない状態になります。なぜこのようなエラーになるのでしょうか?





u16 tx_fifo_set(txfifo_data * txfifo)
{


-------------------(中略)-------------------------------------------------------------


}








void tx_test(cc1101_client * client)
{
u8 i=0;
u8 new_input_data=0;

-------------------(中略)-------------------------------------------------------------


while(1)
{
switch(status)
{


-------------------(中略)-------------------------------------------------------------

case FIFO_SETUP:
if(cnt_sent_packet > 100)
{
status = DATA_WAVEOUT_QUIT;
break;
}


//alert_data_get(&client);

cc1100_cmd_flush_tx();
cc1100_cmd_idle();

cc1100_cmd_calibrate();
cc1100_cfg_gdo0(CC1100_GDOx_SYNC_WORD);
mdelay(5);

client->status.sessionflag = 0x02;//SYN flag set
client->status.ivent_flag = 0xa5;


//tx_length = tx_fifo_set(client);
//tx_fifo_set(&client);
tx_fifo_set(client->txfifo);


udelay(10);

#if 1
cc1100_read_reg_uartout((CC1100_REG_TXBYTES | CC1100_ACCESS_STATUS));
#endif

status = DATA_WAVEOUT;
break;


-------------------(中略)-------------------------------------------------------------


}

現在ATmega88というアトメル社製のマイコンのプログラミングを行っています。コンパイラはwin_avrを使用しています。

現在void tx_test(cc1101_client * client)というcc1101_clientポインターを引数とした関数を作成したのですが、この関数内でu16 tx_fifo_set(txfifo_data * txfifo)という txfifo_dataポインターを引数とする関数を呼び出したいと思っているのですが、これをコンパイルすると

error: incompatible type for argument 1 of 'tx_fifo_set'というエラーが出力されコンパイルできない状態になり...続きを読む

Aベストアンサー

struct _cc1101_client_ で、

> txfifo_data txfifo;

と定義されてるんだから、client->txfifoはtxfifo_data*じゃなくてtxfifo_dataでしょう。

> tx_fifo_set(&client->txfifo);

とすればいいのでは?

> これらのポインター構造を乗せさせて頂きます。

という言い回しも意味不明だし、ポインターについての理解が不足しているのではないですか?

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

Qchar *name1[4] とchar name2[][4] の違いについて

C言語のことで質問があります。

char *name1[4]は
char *name1[4] = {"abcdefghi","jkl","l","mn"};
と宣言でき,ポインタを4つ確保した形となりました。

char name2[][4]は
char name2[][4] = {"abc","def","ghi","jkl","mno","pqr","stu","vwx"};
と4文字以内の文字列を初期化した数だけ確保した形となりました。

この結果からchar *name1[4]の意味は,char name2[][4]ではなくchar name2[4][]に近いと思いました。
しかし,char name2[4][]ではポインタを4つ確保した事にはならないみたいでコンパイルが通りません。
*name1[4]では4つのポインタを確保できるのに~と思ってしまいます。

ポインタと配列は別物と考えるべきなのでしょうか?
訳の分からない質問かもしれませんが,
何卒ご指導いただくようよろしくお願いします。

Aベストアンサー

ポインタと配列の違いというのは、変数と定数の違いのようなものです。

話を簡単にするために、一次元配列から考えましょう。

char *p1; と定義した時のp1は、いうまでもなくポインタで、
これは変数です。p1は任意の文字列を指すことができます。
char a1[4]; と配列の形で定義した場合のa1については、
a1[0]やa1[1]等を、通常のchar型の変数と全く同じように扱うことが
できます。しかし、a1自体は、例えば a1 = p1; のように値を代入する
ことができません。(逆の p1 = a1; は可能。)つまり、この場合のa1は、
変数ではなく、定数のようなものなのです。

複合的なケースについて見てみましょう。
char **q1; ポインタへのポインタ
 q1,*q1,**q1,q1[0],*q1[0],q1[0][0] のいずれも変数として
 扱うことができます。(値を代入することが文法的に許されます。
 ただし、実行時にはアクセス違反になる場合もあります。)
char q2[4][4]; 二次元配列
 q2,q2[0]は変数として扱うことができません。q2[0][0]のように
 して、初めて変数として扱えるようになります。
char *q3[4]; ポインタの配列
 q3は変数として扱うことができませんが、q3[0],*q3[0],q3[0][0]
 はいずれも変数として扱うことができます。
 なお、この定義は char *(q3[4]); とした場合と全く同じ意味です。
char (*q4)[4]; 配列へのポインタ
 q4,(*q4)[0],q4[0][0]はいずれも変数として扱うことができます。
 しかし、*q4,q4[0]は変数として扱うことができません。

char *name1[4]; と char name2[4][]; は確かに似ています。しかし
違うところもあります。それは、name1[0] が変数として扱えるのに
対し、name2[0] には値を代入できないという点です。(データの
具体的な構造については、inthefloiさんが書いておられる通りです。
> char name2[4][]ではポインタを4つ確保した事にはならないみたい
というのも、全くその通りで、配列の定義では、ポインタ変数の領域
を確保する余地はないのです。

ポインタと配列の違いというのは、変数と定数の違いのようなものです。

話を簡単にするために、一次元配列から考えましょう。

char *p1; と定義した時のp1は、いうまでもなくポインタで、
これは変数です。p1は任意の文字列を指すことができます。
char a1[4]; と配列の形で定義した場合のa1については、
a1[0]やa1[1]等を、通常のchar型の変数と全く同じように扱うことが
できます。しかし、a1自体は、例えば a1 = p1; のように値を代入する
ことができません。(逆の p1 = a1; は可能。)つまり...続きを読む

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[VC++][MFC][SDI]ダイアログコントロールもしくわツールバー!!詰まってます!!

現在VC++6.0でMFCを使いSDIのプログラムを作っているのですが、フォームにダイアログバーを張っています。

これをツールバーのように自由に動かしたり、左右上下にドッキングさせたり。
これって実現可能でしょうか?

色々ためしてみたんですが無理でした。
やっぱ不可能ですかね?

これが無理なんであればデフォルトで作成されるツールバー([新規作成][開く][保存]等が入ってる)にコントロール(ボタンやリストボックス)を追加して使用、と考えているのですがこれも難しい!!!


まだまだ未熟者なのですがどうかご存知の方おられましたらご教授ください!!
よろしくお願いします!!

Aベストアンサー

Dannerです。
参考URL(英語)を載せておきます。

参考URL:http://www.codeguru.com/Cpp/controls/toolbar/placingcontrolsintoolbars/article.php/c2505/


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

人気Q&Aランキング