web-dev-qa-db-ja.com

Cで配列を定義

450要素の文字配列がいくつかあります(液晶画面に表示するビットマップデータを保存しています)。それらをヘッダーファイルと#defineの下に配置したいのですが、コンパイルエラーが発生し続けます。 [〜#〜] c [〜#〜]でこれをどのように実行しますか?

#define numbers[450] {0, 1,etc...}

#define numbers {0, 1, etc...}

#define numbers[450]そして、後で数値を設定します

などなど...

9
Reid

まあ...あなたは確かに定義を使用する必要はありません。それらをconst静的配列としてヘッダーに追加するだけです。

/* prevents multiple, redundant includes */
/* make sure to use a symbol that is fairly sure to be unique */
#ifndef TEST_H
#define TEST_H

/* your image data */
const char image[] = { 1, 2, 3, 4, ... };

#endif

また、コンパイルエラーのヘルプが必要な場合は、コードを投稿する必要があります。

10
Ed S.

LCDに表示しているので、これは組み込みシステムだと思います。

ヘッダーにデータを入れないでください。

データを通常のCまたはC++ファイルに入れます。これをコンパイルします。データのみが含まれている場合があり、それで問題はなく、更新も簡単です。

次に、ヘッダーファイルを使用してデータへのアクセスを許可します。

たとえば、images.cファイルでは次のようになります。

#include "images.h"
const byte numbers1[MAX_NUMBERS1] = { ... };
byte numbers2[MAX_NUMBERS2];       // will be initialsied to 0

次に、images.hは次のとおりです。

#ifndef _IMAGES_H_
#define _IMAGES_H_

typedef unsigned char byte;
#define MAX_NUMBERS1 (450)
        // different constants in case you change something        
#define MAX_NUMBERS2 (450)      
       // even better if you can do const static int MAX_NUMBERS1=450; 
       // but depends on the compiler
extern const byte numbers1[MAX_NUMBERS1] = { ... };
extern byte numbers2[MAX_NUMBERS2];       // will be initialised to 0

#endif

その後、プログラム内の他のすべての.cファイルがそれらにアクセスできます。

変数定義をヘッダーファイルに入れることは、(ほとんど)常に悪い考えです。

変数のdeclarationなど。 extern byte numbers2[MAX_NUMBERS2];は、最終的なリンクされたプログラムにnumbers2どこか他の場所という配列変数があることをCコンパイラに伝えています。リンカがその定義を(別の場所から)取得しない場合、割り当てられた変数用のスペースがないため、エラーが発生します。

変数のdefinition(externがないことに注意してください)。 byte numbers2[MAX_NUMBERS2];は、numbers2という配列変数があることをCコンパイラに効果的に伝えており、このソースファイルからの結果のオブジェクトコードで、ここにスペースを割り当てる必要があり、これは値を保持するために使用されます最終的なリンクされたプログラムの変数の。

numbers2のスペースはnot宣言(externが前に付く)を確認するとCコンパイラによって割り当てられ、実際の定義(externなし)を確認すると割り当てられます。

したがって、任意の変数の実際の定義をヘッダーファイルに入れ、それを複数のソースコードファイル(.c)に含めると、Cコンパイラーは変数に複数回スペースを割り当てます。次に、リンカはエラーを出します(通常、同じ名前の複数の定義)。

もっと微妙な問題があります。最初にプログラムを開発するときに、ヘッダーファイルが1つのソースファイルだけである場合、プログラムは正しくコンパイルおよびリンクされます。その後、2番目のソースファイルにヘッダーが含まれている場合(おそらく、元のソースコードファイルを2つのファイルに分割したばかりの可能性があります)、リンカーは「複数の定義」エラーを発生させます。プログラムはコンパイルとリンクに使用されていたため、これは非常に混乱する可能性があり、明らかに何も変更されていません。

概要
ヘッダーファイルに定義を入れて、変数にスペースを割り当てないでください。ヘッダーファイルには変数declarationsのみを入れてください。

8
gbulmer

同様の問題がありました。私の場合、他の静的配列のサイズとして使用するために定数の配列が必要でした。私が使用しようとしたとき

const int my_const_array[size] = {1, 2, 3, ... };

そして宣言します:

int my_static_array[my_const_array[0]];

コンパイラーからエラーが出ます:

array bound is not an integer constant

だから、最後に私は次のことをしました(多分それを行うよりエレガントな方法があるでしょう):

#define element(n,d) ==(n) ? d :
#define my_const_array(i) (i) element(0,1) (i) element(1,2) (i) element(2,5) 0
1
Ojos