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,因此,我需要声明然后在两个单独的行上分配,这在我的代码的其他地方不是真的,所以我完全混淆了-真实的标准。但是在两行上执行此操作时我仍然会遇到相同的错误。

然后我决定使用可用的 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

第一部分

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

这不起作用,因为 C 中的全局变量分为两个空间:数据段bss 段。例如:

#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在示例中一样,甚至不会发生太多事情。相反,正如编译器所说,它在 BSS 段中表示,“我们将需要为未初始化的变量保留 n 字节的内存。” 稍后,程序加载器会注意到这一点,并在您的程序开始运行之前保留这 n 个字节。

因此,在初始化全局变量时尝试 malloc 是没有意义的,因为当创建全局变量时,您的程序还没有运行。malloc 的机器指令甚至可能还没有在内存中!



第二部分

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

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

好的,让我们一点一点地把它从 C# 翻译成 C。你const在 C 中使用是因为常量静态(几乎)是标准英语的同义词吗?因为它们在编程方面非常不同。

  • C 和 C# 中的关键字const意味着变量不能是L-value
  • 面向对象语言(如 C#)中的关键字static意味着函数或变量相对于其类的对象实例是不变的。C没有对象,因此没有类比。
  • 关键字static在纯 C 中使用,表示变量在调用方面是不变的,或者函数在可见位置方面是不变的(类似于privateC#,您可以在此处阅读更多内容)。

但是你真的想在那里做什么?只需为程序保留一大块内存,对吗?C 没有byte数据类型,但char大小为一个字节;你可以改用它。该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

You either:

const char my_array[] = "abcdef";

or:

char *my_array;

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

Example 1 makes no sense because you are attempting to initialize a static variable at runtime. Example 2 makes no sense because you are attempting to modify a const object. Essentially, you did the opposite of what could work in either situation.


What I want to achieve is similar to something in C# like it:

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

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

Ok, then you want;

unsigned char arr[256];

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