繁体   English   中英

变长arrays如何支持数值处理?

[英]How do variable length arrays support numeric processing?

提示:本站为国内最大中英文翻译问答网站,提供中英文对照查看,鼠标放在中文字句上可显示英文原文

我正在阅读C Herbert Schildt的完整参考第 4 版。 第 4 章 - Arrays 和字符串中,它提到“将可变长度 arrays 添加到 C99 的一个主要原因是支持数字处理”。

我的问题是:什么是数字处理 可变长度 arrays 如何支持数字处理

可变长度 arrays 可以出现在三个地方:

  1. 自动局部变量。
  2. 动态分配arrays。
  3. Function个参数。

自动局部变量可能会有问题——它们占用堆栈空间,并且没有可移植的方法来确定是否有足够的堆栈空间来分配您要创建的数组。 如果没有足够的空间,程序将单方面停止; 无法从错误中恢复。 这让很多人反对 VLA。

动态分配的 arrays 没有问题——尽管这种表示法不是特别方便。 您可以判断分配何时失败并做出适当的反应。

Function 参数是灵活性发挥作用的地方——尤其是对于 2D arrays(以及更高维度)。

在引入 VLA 之前,您必须要么将数组视为一维向量并手动计算索引,要么必须为每个不同大小的矩阵编写不同的函数,或者至少为每个不同的列数编写不同的函数。

你可以使用:

enum { NCOLS = 8 };
static void dump_array(const char *tag, size_t nrows, int array[][NCOLS])
{
    printf("%s: (%zux%d)\n", tag, nrows, NCOLS);  // Note %zu vs %d!
    for (size_t r = 0; r < nrows; r++)
    {
        for (size_t c = 0; c < NCOLS; c++)
            printf(" %5d", array[r][c]);
        putchar('\n');
    }
}

就目前而言这很好,但是如果您想要具有不同列数的矩阵,则必须编写(和调用)不同的函数。

另一种方法是使用大的一维向量并计算代码中的二维下标:

static void dump_array(const char *tag, size_t nrows, size_t ncols, int array[])
{
    printf("%s: (%zux%zu)\n", tag, nrows, ncols);
    for (size_t r = 0; r < nrows; r++)
    {
        for (size_t c = 0; c < ncols; c++)
            printf(" %5d", array[r * ncols + c]);
        putchar('\n');
    }
}

但是,使用 arguments 的 VLA 表示法,您可以编写一个 function 来打印任何二维矩阵(给定的基本类型)并使用直接下标表示法以获得最大的便利:

static void dump_array(const char *tag, size_t nrows, size_t ncols, int array[nrows][ncols])
{
    printf("%s: (%zux%zu)\n", tag, nrows, ncols);
    for (size_t r = 0; r < nrows; r++)
    {
        for (size_t c = 0; c < ncols; c++)
            printf(" %5d", array[r][c]);
        putchar('\n');
    }
}

符号上没有太大区别,但灵活性的提高是巨大的。 例如,您可以编写适用于任何大小的矩阵的单个矩阵乘法 function,而在 VLA 可用之前,只有一维版本可以处理任意大小的数组。

动态分配相当简单,但并不十分明显:

/* SO 7531-3779 */

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

static void dump_array(const char *tag, size_t rows, size_t cols, int array[rows][cols])
{
    printf("%s (%zux%zu):\n", tag, rows, cols);
    for (size_t r = 0; r < rows; r++)
    {
        printf("%2zu:", r);
        for (size_t c = 0; c < cols; c++)
            printf(" %5d", array[r][c]);
        putchar('\n');
    }
}

int main(void)
{
    size_t rows = 13;
    size_t cols = 8;
    int (*array)[8] = malloc(sizeof(int [rows][cols]));

    for (size_t r = 0; r < rows; r++)
    {
        int sign = -1;
        for (size_t c = 0; c < cols; c++)
        {
            array[r][c] = sign * ((r + 1) * 100 + c + 1);
            sign = -sign;
        }
    }

    dump_array("Array 1", rows, cols, array);

    free(array);
    return 0;
}

Output:

Array 1 (13x8):
 0:  -101   102  -103   104  -105   106  -107   108
 1:  -201   202  -203   204  -205   206  -207   208
 2:  -301   302  -303   304  -305   306  -307   308
 3:  -401   402  -403   404  -405   406  -407   408
 4:  -501   502  -503   504  -505   506  -507   508
 5:  -601   602  -603   604  -605   606  -607   608
 6:  -701   702  -703   704  -705   706  -707   708
 7:  -801   802  -803   804  -805   806  -807   808
 8:  -901   902  -903   904  -905   906  -907   908
 9: -1001  1002 -1003  1004 -1005  1006 -1007  1008
10: -1101  1102 -1103  1104 -1105  1106 -1107  1108
11: -1201  1202 -1203  1204 -1205  1206 -1207  1208
12: -1301  1302 -1303  1304 -1305  1306 -1307  1308

VLA 表示法也可以与固定大小的 arrays 一起使用——全局或本地。 也就是说,只要您准确描述 arrays,就可以将普通的 arrays 传递给接受 VLA 的函数:

/* SO 7531-3779 */

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

static void dump_array(const char *tag, size_t rows, size_t cols, int array[rows][cols])
{
    printf("%s (%zux%zu):\n", tag, rows, cols);
    for (size_t r = 0; r < rows; r++)
    {
        printf("%2zu:", r);
        for (size_t c = 0; c < cols; c++)
            printf(" %5d", array[r][c]);
        putchar('\n');
    }
}

/* Created by: gen_matrix -r 9 -c 5 -L -9999 -H +9999 -x -n matrix1 -w5 -E */
/* Random seed: 0x7F3F1FA0 */
int matrix1[9][5] =
{
    {  9337,  5320,  5059,  1115,    14, },
    { -7514, -1643,  8461,  1613,  6968, },
    {  2469,  8307, -8045,  2327, -7862, },
    {  8174, -7062,   666, -3480,  1836, },
    { -2400, -7863, -1859,  2436, -6840, },
    {  5819, -4112, -2037,  9005, -9748, },
    {   823, -9687,  1245, -2074,  3741, },
    {  4812, -9254, -6365, -1263, -9265, },
    { -9400, -5479, -3756, -7417, -5726, },
};
enum { MATRIX1_ROWS = 9, MATRIX1_COLS = 5 };

int main(void)
{
    /* Created by: gen_matrix -E -r 13 -c 8 -H 999 -L -999 -i -w4 -n matrix2 */
    /* Random seed: 0x64347CFE */
    int matrix2[13][8] =
    {
        {  -27, -268,   73,  112, -148,  407, -411,  418, },
        { -782,  368, -306, -830, -851,    9,  505,   33, },
        { -558, -979,  471,  376, -290, -270, -910,  812, },
        { -374,  201,  454,  966,  -39,  653, -747, -664, },
        {  322,  385, -141, -326,   37,  941, -298, -281, },
        {  529,   68, -995,  -30, -942, -670,  563, -244, },
        {  773,   46, -315, -363,  732,  218,  230,  536, },
        {  566, -164, -493,  568, -256, -196, -635, -387, },
        {  452, -348,   79,  103, -416, -756,  688, -473, },
        { -294, -641,  530, -307,  508,  878, -786, -745, },
        {  427,  462, -229,  253,  116, -804,  -72,  -35, },
        { -776,  290,  158,  154,  662, -621,  576,  388, },
        {  999, -684, -207, -506,  708, -949,  149, -969, },
    };
    enum { MATRIX2_ROWS = 13, MATRIX2_COLS = 8 };

    dump_array("Matrix 1", MATRIX1_ROWS, MATRIX1_COLS, matrix1);
    dump_array("Matrix 2", MATRIX2_ROWS, MATRIX2_COLS, matrix2);

    return 0;
}

Output:

Matrix 1 (9x5):
 0:  9337  5320  5059  1115    14
 1: -7514 -1643  8461  1613  6968
 2:  2469  8307 -8045  2327 -7862
 3:  8174 -7062   666 -3480  1836
 4: -2400 -7863 -1859  2436 -6840
 5:  5819 -4112 -2037  9005 -9748
 6:   823 -9687  1245 -2074  3741
 7:  4812 -9254 -6365 -1263 -9265
 8: -9400 -5479 -3756 -7417 -5726
Matrix 2 (13x8):
 0:   -27  -268    73   112  -148   407  -411   418
 1:  -782   368  -306  -830  -851     9   505    33
 2:  -558  -979   471   376  -290  -270  -910   812
 3:  -374   201   454   966   -39   653  -747  -664
 4:   322   385  -141  -326    37   941  -298  -281
 5:   529    68  -995   -30  -942  -670   563  -244
 6:   773    46  -315  -363   732   218   230   536
 7:   566  -164  -493   568  -256  -196  -635  -387
 8:   452  -348    79   103  -416  -756   688  -473
 9:  -294  -641   530  -307   508   878  -786  -745
10:   427   462  -229   253   116  -804   -72   -35
11:  -776   290   158   154   662  -621   576   388
12:   999  -684  -207  -506   708  -949   149  -969
问题未解决?试试搜索: 变长arrays如何支持数值处理?
暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2023 STACKOOM.COM