C:交换二维数组中的值的函数

发布于 2024-08-06 02:48:15 字数 695 浏览 8 评论 0原文

我正在尝试编写一个函数来交换 2D 数组中的 2 个元素:

void swap(int surface[][], int x1, int y1, int x2, int y2) {
    int temp = surface[x1][y1];
    surface[x1][y1] = surface[x2][y2];
    surface[x2][y2] = temp;
}

但是,当我尝试编译它(gcc)时,我收到此错误消息:

Sim_Annealing.c: In function `swap': 
Sim_Annealing.c:7: error: invalid use of array with unspecified bounds
Sim_Annealing.c:8: error: invalid use of array with unspecified bounds
Sim_Annealing.c:8: error: invalid use of array with unspecified bounds
Sim_Annealing.c:9: error: invalid use of array with unspecified bounds

是否有一些特殊的魔法我必须做才能拥有 2D 数组作为函数参数?

感谢您的帮助。如果您知道任何关于数组作为函数参数的好参考,请将它们发送给我:)

I'm trying to write a function to swap 2 elements in a 2D array:

void swap(int surface[][], int x1, int y1, int x2, int y2) {
    int temp = surface[x1][y1];
    surface[x1][y1] = surface[x2][y2];
    surface[x2][y2] = temp;
}

however when I try to compile it (gcc), I get this error message:

Sim_Annealing.c: In function `swap': 
Sim_Annealing.c:7: error: invalid use of array with unspecified bounds
Sim_Annealing.c:8: error: invalid use of array with unspecified bounds
Sim_Annealing.c:8: error: invalid use of array with unspecified bounds
Sim_Annealing.c:9: error: invalid use of array with unspecified bounds

Is there some special magic I have to do in order to have a 2D array as a function parameter?

Thanks for your help. If you know of any good references for arrays as function parameters send them my way :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

挽梦忆笙歌 2024-08-13 02:48:15

只需声明数组参数即可。更好的是,对初始声明和函数的形式参数都使用 typedef。

问题是,在不知道行大小(即列数)的情况下,它无法计算指针调整以获得后续行。有趣的是,它不需要知道您有多少行。

例如,这是可行的:

void swap(int surface[][20], int x1, int y1, int x2, int y2) {
  int temp = surface[x1][y1];
    surface[x1][y1] = surface[x2][y2];
    surface[x2][y2] = temp;
}

但最好将调用者的类型和函数的类型联系在一起。


每个下标访问都需要乘法,但这有效(仅符合 C99 的编译器)...

int f(int, int, int a[*][*]);

int f(int r, int c, int a[r][c])
{
  return a[99][100];
}

另一个例子,即使在 C89 之前的环境中也可以工作:

typedef int surface_t[][20];

surface_t therealthing = {
  { 1, 2, 3},
  { 4, 5, 6}
};

void swap(surface_t x) {
  x[0][2] = 'q';
}

void f1(void) {
  swap(therealthing);
}

最后,因为可变长度数组是最近出现的、传统的且仍然存在的东西最快的技术是传递int *a[]。这不需要任何行或列长度的知识,但您确实需要构造指针向量。

Just declare the array parameters. Better yet, use a typedef for both the initial declaration and the function's formal parameter.

The problem is that without knowing the row size, i.e., the number of columns, it has no way to compute the pointer adjustment to get subsequent rows. Interestingly, it does not need to know how many rows you have.

For example, this works:

void swap(int surface[][20], int x1, int y1, int x2, int y2) {
  int temp = surface[x1][y1];
    surface[x1][y1] = surface[x2][y2];
    surface[x2][y2] = temp;
}

But it would be better to tie the caller's types and the function's type together.


Every subscript access will require a multiply, but this works (only C99-conforming compilers) ...

int f(int, int, int a[*][*]);

int f(int r, int c, int a[r][c])
{
  return a[99][100];
}

Another example, which would work in even pre-C89 environments:

typedef int surface_t[][20];

surface_t therealthing = {
  { 1, 2, 3},
  { 4, 5, 6}
};

void swap(surface_t x) {
  x[0][2] = 'q';
}

void f1(void) {
  swap(therealthing);
}

And finally, because variable length arrays are something quite recent, the traditional and still the fastest technique is to pass int *a[]. This doesn't require any knowledge of either row or column lengths, but you do need to construct the pointer vector.

臻嫒无言 2024-08-13 02:48:15

如果数组是“真正的”二维数组,则需要指定除第一个维度之外的所有维度的大小:

void swap(int surface[][NUMBER_OF_COLUMNS], int x1, int y1, int x2, int y2) {
    ...
}

这存在一些潜在的问题。如果您的 2D 数组实际上是指针数组 (int *surface[]),那么这是行不通的,您需要将 surface 参数更改为指向指针:

void swap(int **surface, int x1, int y1, int x2, int y2) {
    ...
}

或者,为了使该函数更通用,您可以将其更改为接受两个 int 指针(可以指向任何地方)并交换它们:

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

您可以这样调用它:

swap(&surface[x1][y1], &surface[x2][y2]);

If the array is a "real" 2D array, you need to specify the size of all but the first dimension:

void swap(int surface[][NUMBER_OF_COLUMNS], int x1, int y1, int x2, int y2) {
    ...
}

There are a few potential problems with this. If your 2D arrays are really arrays of pointers (int *surface[]), that won't work, and you need to change the surface parameter to a pointer to a pointer:

void swap(int **surface, int x1, int y1, int x2, int y2) {
    ...
}

Or, to make the function more general, you could change it to accept two int pointers (that could point anywhere) and swap them:

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

and you would call it like this:

swap(&surface[x1][y1], &surface[x2][y2]);
深居我梦 2024-08-13 02:48:15

在 C 中,只允许数组的第一个维度不指定,因为它需要知道如何计算偏移量。如果您需要使用可变大小的二维数组,请以 int* 的形式传入我们的数组,然后传入第二维的大小并自行传递给指针数学:

void swap(int *surface, int ySize, int x1, int y1, int x2, int y2) {
    int temp = *(surface + ySize * x1 + y1) ;
    *(surface + ySize * x1 + y1) = *(surface + ySize * x2 + y2);
    *(surface + ySize * x2 + y2) = temp;
}

这与 [][] 语法所做的事情相同,因为 C 中的数组实际上只是指针。

In C only the first dimension of the array is allowed to be left unspecified, because it needs to know how to calculate the offsets. If you need to work with a variable sized 2D array pass in our array as an int*, pass in the size of your second dimensions and to the pointer math yourself:

void swap(int *surface, int ySize, int x1, int y1, int x2, int y2) {
    int temp = *(surface + ySize * x1 + y1) ;
    *(surface + ySize * x1 + y1) = *(surface + ySize * x2 + y2);
    *(surface + ySize * x2 + y2) = temp;
}

This is the same thing that the [][] syntax is doing, since arrays in C are really just pointers.

木緿 2024-08-13 02:48:15

GCC 允许可变长度数组作为函数的参数:

#include <stdio.h> 

void swap(int size; int surface[][size], int size, int x1, int y1, int x2, int y2) {
  int temp = surface[x1][y1];
  surface[x1][y1] = surface[x2][y2];
  surface[x2][y2] = temp;
}

int s[10][10];

int main(){
  s[1][1] = 11;
  s[2][2] = 22;

  printf("s[1][1]: %i   s[2][2]: %i\n", s[1][1], s[2][2] );
  swap( s, 10, 1, 1, 2, 2 );
  printf("s[1][1]: %i   s[2][2]: %i\n", s[1][1], s[2][2] );

  return 0;
}

GCC allows variable-length arrays as arguments to functions:

#include <stdio.h> 

void swap(int size; int surface[][size], int size, int x1, int y1, int x2, int y2) {
  int temp = surface[x1][y1];
  surface[x1][y1] = surface[x2][y2];
  surface[x2][y2] = temp;
}

int s[10][10];

int main(){
  s[1][1] = 11;
  s[2][2] = 22;

  printf("s[1][1]: %i   s[2][2]: %i\n", s[1][1], s[2][2] );
  swap( s, 10, 1, 1, 2, 2 );
  printf("s[1][1]: %i   s[2][2]: %i\n", s[1][1], s[2][2] );

  return 0;
}
杀手六號 2024-08-13 02:48:15

将多维数组作为函数参数传递会带来一些麻烦。请记住,在大多数情况下,数组类型的表达式将隐式转换为指针类型,其值将是数组第一个元素的地址。例如,一个 10x20 的 int 数组将被转换为一个指向 20 个元素的 int 数组的指针:

void swap(int (*surface)[20], size_t rows, size_t x1, size_t x2, 
          size_t y1, size_t y2)
{
  int temp;
  assert(x1 < rows && x2 < rows);
  temp = surface[x1][y1];
  surface[x1][y1] = surface[x2][y2];
  surface[x2][y2] = temp;
}
int main(void)
{
  int surface[10][20];
  ...
  swap(surface, 10, 1, 1, 2, 2);
  ...
}

这里就出现了一个大问题。从其原型来看,swap()只能处理Nx20个int数组;行数可以变化,但列数不能变化,因为 T (*)[N]T (*)[M] 是不同的类型,其中 N != M。理想情况下,您希望有一个可以处理任意数量的行和列的函数。实现此目的的一种方法是将数组视为 T 的一维数组,并手动计算行和列偏移:

void swap(int *surface, size_t rows, size_t cols, size_t x1, 
          size_t x2, size_t y1, size_t y2)
{
  int temp;
  assert(x1 < rows && x2 < rows && y1 < cols && y2 < cols);
  temp = surface[x1*cols+y1];
  surface[x1*cols+y1] = surface[x2*cols+y2];
  surface[x2*cols+y2] = temp;
}
int main(void)
{
  int surface[10][20];
  ...
  swap(&surface[0][0], 10, 20, 1, 1, 2, 2);
}

这里我们传递第一个元素的地址 (&surface[0][0]) 并将其视为指向 int 的简单指针。这样我们就可以处理任意数量的行和列。请注意,这仅适用于实际的 2D 数组(不适用于指针数组),因为交换假定数组元素是连续放置的。

Passing multidimensional arrays as function arguments introduces some headaches. Remember that in most contexts, an expression of array type will be implicitly converted to a pointer type, and its value will be the address of the first element of the array. So for example, a 10x20 array of int will be converted to a pointer to a 20-element array of int:

void swap(int (*surface)[20], size_t rows, size_t x1, size_t x2, 
          size_t y1, size_t y2)
{
  int temp;
  assert(x1 < rows && x2 < rows);
  temp = surface[x1][y1];
  surface[x1][y1] = surface[x2][y2];
  surface[x2][y2] = temp;
}
int main(void)
{
  int surface[10][20];
  ...
  swap(surface, 10, 1, 1, 2, 2);
  ...
}

Here's where a big problem shows up. Based on its prototype, swap() can only deal with Nx20 arrays of int; the number of rows can vary, but the number of columns cannot, because T (*)[N] is a different type from T (*)[M] where N != M. Ideally you'd like a function that can deal with an arbitrary number of rows and columns. One way to accomplish that is to treat the array as a 1D array of T, and compute row and column offsets manually:

void swap(int *surface, size_t rows, size_t cols, size_t x1, 
          size_t x2, size_t y1, size_t y2)
{
  int temp;
  assert(x1 < rows && x2 < rows && y1 < cols && y2 < cols);
  temp = surface[x1*cols+y1];
  surface[x1*cols+y1] = surface[x2*cols+y2];
  surface[x2*cols+y2] = temp;
}
int main(void)
{
  int surface[10][20];
  ...
  swap(&surface[0][0], 10, 20, 1, 1, 2, 2);
}

Here we pass the address of the first element (&surface[0][0]) and treat it as a simple pointer to int. That way we can deal with any number of rows and columns. Note that this will only work for actual 2D arrays (not arrays of pointers), since swap assumes that the array elements are laid out contiguously.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文