0

私の VS2012 Windows Phone プロジェクトの一部は C です。ある日、配列を初期化してその中に何かを入れようとして苦労しました。

グローバル (関数外) として初期化しようとすると、const ではない値で初期化できないというメッセージが表示されます。

const char* myArray = (const char*)malloc(256);
// Bad code: this isn't initialized with a const

値で初期化しないと、値を指定するようにというメッセージが表示されます。そのため、配列に NULL 値を割り当てます。

const char* myArray = NULL;

次に、どこかにサイズを設定する必要があるため、メイン関数または最初の関数内でサイズを設定します。

int myFirstFunctionInTheCode()
{
    myArray = (char*)malloc(256);    
}

次に、「;」のようなものを取得します。タイプの前に期待される

だから私はフォーラムを検索していて、Visual Studio の C は C89 であることを読んだので、宣言してから 2 つの別々の行に割り当てる必要がありますが、これは私のコードの他の場所には当てはまらないため、完全に混乱しています-リアル-基準。しかし、2行で実行しても同じエラーが発生します。

次に、利用可能な VS ライブラリの他のツールを使用して、C では sstream や streambuf などを含めることができないことを確認することにしました。そうしないと、プロジェクト全体が何千ものバグで失敗します。したがって、boost を使用して実際のストリーム ライブラリを取得できますが、一部のスレッドが使用されているため、Windows Phone とは互換性がありません。

C (Visual Studio) でグローバル固定サイズ配列内に値を設定するにはどうすればよいですか?

私が達成したいのは、次のようなC#の何かに似ています:

static byte[] gentleCSharpArray = new byte[256];

private void easyShotCSharpFunction()
{
    gentleCSharpArray[0] = 0x57;
    gentleCSharpArray[1] = 0x54;
    gentleCSharpArray[2] = 0x46;
}

配列に値を代入するのにそれほど時間をかけたことがないので、グローバルな char* 配列を完全に間違っていると思いますか?

4

2 に答える 2

3

パート1

const char* myArray = (const char*)malloc(256);

C のグローバル変数はデータ セグメントbss セグメントの 2 つのスペースに分割されるため、これは機能しません。例えば:

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

int* myArray; // uninitialized, represented by bss segment
const char* myArray2 = "abc"; // initialized, goes into data segment

int main ()
{
    myArray = malloc(3*sizeof(int));
    myArray[0] = 111;
    myArray[1] = 222;
    myArray[2] = 333;

    int i;
    for (i=0; i<3; i++)
        printf("%d, %c\n", myArray[i], myArray2[i]);
    return 0;
}

これをコンパイルすると、const char* myArray2 = "abc";機械語命令に変換されません。代わりに、メモリ内で「abc」がどのように見えるかのイメージが作成され、初期化された他のすべてのグローバル変数とともにデータ セグメントに配置されます。その後、プログラム ローダーは、プログラムが実行を開始する前に、そのデータ セグメント全体を取得してメモリに貼り付けます。

例のように、初期化されていない変数でmyArrayは、それほど多くは発生しません。むしろ、コンパイラが「初期化されていない変数用に予約された n バイトのメモリが必要になる」と言うように、BSS セグメントで表されます。後で、プログラムローダーはこれに注意し、プログラムが実行を開始する前に、それらの n バイトを予約します。

したがって、グローバル変数を初期化するときに malloc を試みても意味がありません。なぜなら、グローバル変数が作成されたとき、プログラムはまだ実行されていないからです。malloc のマシン命令は、まだメモリ内にない可能性があります。



パート2

static byte[] gentleCSharpArray = new byte[256];

private void easyShotCSharpFunction()
{
    gentleCSharpArray[0] = 0x57;
    gentleCSharpArray[1] = 0x54;
    gentleCSharpArray[2] = 0x46;
}

さて、これを少しずつ C# から C に翻訳しましょう。標準英語では定数静的は (ほぼ) 同義語であるconstため、C を使用していますか? それらはプログラミングにおいて非常に異なるからです。

  • constC および C#のキーワードは、変数がL-valueにならないことを意味します。
  • オブジェクト指向言語 (C# など)のキーワードstaticは、関数または変数がそのクラスのオブジェクト インスタンスに関して不変であることを意味します。C にはオブジェクトがないため、アナログがありません。
  • このキーワードstaticはプレーン C で使用され、呼び出しに関して変数が不変であること、または関数が表示される場所に関して不変であることを意味します ( privateC# と同様に、詳細はこちらを参照してください)。

でも、そこで本当にやりたいことは何ですか?プログラム用に大量のメモリを予約するだけですよね?C にはbyteデータ型はありませんがchar、サイズは 1 バイトです。代わりにそれを使用できます。キーワードは、unsignedこれが文字列に使用されないことをプログラム インスペクタに明確にします。

// Compiled and ran with gcc -O0 -g -Wall on Ubuntu
#include <stdio.h>
#include <stdlib.h>

int* myArray;
const char* myArray2 = "abc";
unsigned char gentleCArray[256]; // <-- here's the declaration you want

static void easyShotCFunction()
{
    gentleCArray[0] = 0x57;
    gentleCArray[1] = 0x54;
    gentleCArray[2] = 0x46;
}

int main ()
{
    myArray = malloc(3*sizeof(int));
    myArray[0] = 111;
    myArray[1] = 222;
    myArray[2] = 333;

    easyShotCFunction();

    int i;
    for (i=0; i<3; i++)
        printf("%d, %c, 0x%x\n", myArray[i], myArray2[i], gentleCArray[i]);

    return 0;
}

プログラムが開始gentleCArrayされると、 はすでに 256 バイトのメモリへのポインターであり、おそらくすべてゼロです。これは、パート 1 で説明した BSS セグメントの結果です。malloc を使用せずに独自のメモリ管理を行う場合に役立ちます。

于 2013-09-01T04:57:48.417 に答える
2

次のいずれか:

const char my_array[] = "abcdef";

また:

char *my_array;

int main(void)
{
    my_array = malloc(some_size);
    /* initialize elements of my_array */
}

実行時に静的変数を初期化しようとしているため、例 1 は意味がありません。const オブジェクトを変更しようとしているため、例 2 は意味がありません。基本的に、どちらの状況でも機能することの反対を行いました。


私が達成したいのは、次のようなC#の何かに似ています:

static byte[] gentleCSharpArray = new byte[256];

private void easyShotCSharpFunction()
{
    gentleCSharpArray[0] = 0x57;
    gentleCSharpArray[1] = 0x54;
    gentleCSharpArray[2] = 0x46;
}

わかりました。

unsigned char arr[256];

void c_version(void)
{
    arr[0] = 0x57;
    arr[1] = 0x54;
    arr[2] = 0x46;
}
于 2013-09-01T03:16:43.957 に答える