[英]How do variable length arrays support numeric processing?
提示:本站为国内最大中英文翻译问答网站,提供中英文对照查看,鼠标放在中文字句上可显示英文原文。
我正在阅读C Herbert Schildt的完整参考第 4 版。 在第 4 章 - Arrays 和字符串中,它提到“将可变长度 arrays 添加到 C99 的一个主要原因是支持数字处理”。
我的问题是:什么是数字处理? 可变长度 arrays 如何支持数字处理?
可变长度 arrays 可以出现在三个地方:
自动局部变量可能会有问题——它们占用堆栈空间,并且没有可移植的方法来确定是否有足够的堆栈空间来分配您要创建的数组。 如果没有足够的空间,程序将单方面停止; 无法从错误中恢复。 这让很多人反对 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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.