【问题标题】:Accessing elements of large array访问大数组的元素
【发布时间】:2018-05-27 04:06:38
【问题描述】:

我在访问我的一个数组的元素时遇到问题。我事先为长代码道歉,但有必要充分解释问题。我有一个结构,我在头文件中声明如下:

typedef struct {
    // DC the current value of the Program Counter register
    unsigned short int DC;

    // PSR : Processor Status Register, bit[0] = P, bit[1] = Z, bit[2] = N, bit[15] = privilege bit
    unsigned short int GSR;

    //Registers - 8
    unsigned short int R[8];

    //Control signals 
    ControlSignals control_signals;

    //Memory 
    unsigned short int mem[65536];
} MachineState;

在链接器文件中,我从二进制文件中读取数据并将 16 位十六进制值存储到 memory 结构数组中。以下是该操作的相关设置:

//Rectify endianness
        if ((foo_array[0]) == 0xDECA || (foo_array[0]) == 0xB7C3 || (foo_array[0]) == 0x7EF1 || (foo_array[0]) == 0x5E71)
        {
            //Iterate through each element in array, swapping bytes to convert to big endian
            for (i = 0; i < bytes; i++)
            {
                //Swap bytes
                (foo_array[i]) = ((foo_array[i])>>8) | ((foo_array[i])<<8);
            }
        }

        //Iterate through temp array selecting only CADE/DADA instructions to copy to struct array
        for (i = 0; i < bytes; i++)
        {
            if ((foo_array[i]) == 0xCADE || (foo_array[i]) == 0xDADA)
            {

                //Increment to starting address
                i++;

                //Store start address
                start_address = foo_array[i];

                //Increment to n-body word specification
                i++;

                //Find number of words in relevant instructions
                foo = foo_array[i];

                //Increment to beginning of instruction
                i++;

                //Iterate through temp array selecting only CADE/DADA instructions to copy to struct array
                for (count = 0, j = start_address; count < foo; i++, j++, count++)
                {

                    //Assign values from temp array to machine memory array
                    machine->mem[j] = foo_array[i];
                    printf("address %05d in memory is: 0x%04X\n",j, machine->mem[j] );                          
                }

                //Once loop exited, decrement index variable to appropriate values
                if (count == foo)
                {
                    i--;
                }
            }   
        }

正如您可能想象的那样,在机器内存的输出中,会有十六进制值、一些零和非零,如下所示:

address 32805 in memory is: 0x0201
address 32806 in memory is: 0x0000
address 32807 in memory is: 0x8000
address 32808 in memory is: 0x0000
address 33280 in memory is: 0x9E00
address 33281 in memory is: 0x8000
address 40960 in memory is: 0x0001

我存储在数组中的值需要传递给要操作的函数,但是我无法找到一种方法来传递 all 那些填充数组的值.数组很长,从索引 0x0000 到 0x10000,但我想传入所有值的唯一方法是在 for 循环中,当我点击数组中的第一个非零元素时选择 for,但问题是,零值也很重要,也必须使用。到目前为止,这是我对循环的实现:

 //Iterate through each element passing populated elements into function
        for (i = 0; i < (sizeof(machine.mem)) / (sizeof(unsigned short int)); i++)
        {
          //  printf("index is %d\n",i );
            if (machine.mem[i] != 0)
            {        
                printf("machine memory is: 0x%04X\n",machine.mem[i] );

                //Call UpdateMachineState to begin decoding machine instructions and execute one LC4 datapath
               //UpdateMachineState(&machine);   
            }
        } 

它只允许我找到非零值,但是如果数组中的起始数字或中间值为零怎么办?他们将被完全错过。有没有办法获得所有填充的值?我似乎无法弄清楚这一点。

编辑: 从收到的 cmets 看来,可能不清楚实际问题是什么,所以我会尽力澄清。加载到机器内存后其内容如下:

address 00000 in memory is: 0xF020
address 00001 in memory is: 0x9A00
address 00002 in memory is: 0xDBA0
address 00003 in memory is: 0x7B40
address 00004 in memory is: 0xF0FF
address 32800 in memory is: 0x9600
address 32801 in memory is: 0xD7A0
address 32802 in memory is: 0x9802
address 32803 in memory is: 0x78C0
address 32804 in memory is: 0x64C0
address 32805 in memory is: 0x0201
address 32806 in memory is: 0x0000
address 32807 in memory is: 0x8000
address 32808 in memory is: 0x0000
address 33280 in memory is: 0x9E00
address 33281 in memory is: 0x8000
address 40960 in memory is: 0x0001

这里的索引 00000 是起始地址,索引 40960 是结束地址。问题是我不知道如何设置 for 循环,以便我可以将已加载到 machine.mem 结构中的所有内容传递给函数 UpdateMachineState(&amp;machine);值 0x0000(例如地址 32806 和 32808)。当声明 struct machine.mem 时,它的所有值都会自动设置为零,所以我不确定如何区分预设的 0x0000 值和此处加载的值:machine-&gt;mem[j] = foo_array[i]。如有必要,我可以发布完整的代码。

【问题讨论】:

  • 确定 (sizeof(machine.memory)) / (sizeof(unsigned short int)) 是正确的,如果没有你的 mem[i]!= 0,如果大小没问题,循环应该打印所有项目,
  • 考虑使用(sizeof(machine.mem)) / (sizeof(machine.mem[0])
  • 什么是memory,它与mem 有什么关系?请复制并粘贴您的 rea 代码。
  • 问题出在哪里还不是很清楚。您是否尝试免费从数组中获取所有非零值?这是不可能的,您需要遍历数组并检查每个值。如果您想要一个数组中的所有非零值,您需要将它们一个一个地复制到 另一个 数组中。
  • 请发minimal reproducible example 进行演示。您显示的代码不完整,无法验证。我怀疑它也不是最小的,尽管省略一些显示的代码,一些努力可能会允许证明问题。

标签: c struct typedef


【解决方案1】:

当声明 struct machine.mem 时,它的所有值都是 自动设置为零,所以我不知道如何区分 预设的 0x0000 值和此处加载的值: machine->mem[j] = foo_array[i].

您可以创建一个包含带有内存值的标志的结构,并在分配内存值时设置该标志。

像这样:

typedef struct{
    unsigned short int value;
    bool value_assigned;
}mem_t;

然后,当您声明 MachineState 结构时,您只需将 mem 声明为这些结构的数组,如下所示:

typedef struct {
    // DC the current value of the Program Counter register
    unsigned short int DC;

    // PSR : Processor Status Register, bit[0] = P, bit[1] = Z, bit[2] = N, bit[15] = privilege bit
    unsigned short int GSR;

    //Registers - 8
    unsigned short int R[8];

    //Control signals 
    ControlSignals control_signals;

    //Memory 
    mem_t mem[65536];
} MachineState;

然后在您分配内存值的代码部分中,您只需要确保设置该标志。

//Iterate through temp array selecting only CADE/DADA instructions to copy to struct array
for (count = 0, j = start_address; count < foo; i++, j++, count++)
{

    //Assign values from temp array to machine memory array
    machine->mem[j].value = foo_array[i];
    machine->mem[j].value_assigned = true;
    printf("address %05d in memory is: 0x%04X\n",j, machine->mem[j]);

}

现在您应该能够遍历该数组并检查value_assigned == true

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-19
    • 1970-01-01
    • 2016-06-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多