有人可以帮我翻译这个c ++代码到c?

时间:2010-01-29 15:14:29

标签: c++ c translation

这是一个神奇的方形生成器,但不知道C ++,我在转换此代码时遇到一些困难:

#include <vector>
#include <iostream>
using namespace std;
//There two series will be on even in case of magic square
// One of even order will be for multiple of 4
void BuildDoublyEvenMagicSquare(vector<vector<int> > &mat, int Order);
//Other of even order will be for multiple of 2
void SinglyEvenMagicSquare(vector<vector<int> > &mat, int order);
// For odd order
void BuildOddMagicSquare(vector<vector<int> > &mat, int Order);

// For odd order
void BuildOddMagicSquare(vector<vector<int> > &mat, int Order)
{
  int SqrOfOrder = Order * Order;
  int start=0, mid=Order/2;     // start position
  for (int loop=1; loop<=SqrOfOrder; ++loop)
  {
    mat[start--][mid++] = loop;
    if (loop % Order == 0)
    {
      start += 2;
      --mid;
    }
    else
    {
      if (mid==Order)
        mid -= Order;
      else if (start<0)
        start += Order;
    }
  }
}

void BuildDoublyEvenMagicSquare(vector<vector<int> > &mat, int Order)
{
  vector<vector<int> > A(Order, vector<int> (Order, 0));
  vector<vector<int> > B(Order, vector<int> (Order, 0));
  int i, j;
  //Building of matrixes I and  J
  int index=1;
  for (i=0; i<Order; i++)
    for (j=0; j<Order; j++)
    {
      A[i][j]=((i+1)%4)/2;
      B[j][i]=((i+1)%4)/2;
      mat[i][j]=index;
      index++;
    }
  for (i=0; i<Order; i++)
    for (j=0; j<Order; j++)
    {
      if (A[i][j]==B[i][j])
        mat[i][j]=Order*Order+1-mat[i][j];
    }
}

void BuildSinglyEvenMagicSquare(vector<vector<int> > &mat, int order)
{
  int ho=order/2;

  vector<vector<int> > C(ho, vector<int> (ho, 0));

   // For Order is Odd
    if (order%2==1)
      BuildOddMagicSquare(C, order);

   // For Order is Even
   else
   {
    //For Order is Doubly Even Order
    if (order % 4==0)
      BuildDoublyEvenMagicSquare(C, order);
     //For Order is Singly Even Order
    else
      BuildSinglyEvenMagicSquare(C, order);
   }
  int i, j, k;
  for (i=0; i<ho; i++)
    for (j=0; j<ho; j++)
    {
      mat[i][j]=C[i][j];
      mat[i+ho][j]=C[i][j]+3*ho*ho;
      mat[i][j+ho]=C[i][j]+2*ho*ho;
      mat[i+ho][j+ho]=C[i][j]+ho*ho;
    }
  if (order==2)
    return;

  vector<int> A(ho, 0);
  vector<int> B;

  for (i=0; i<ho; i++)
    A[i]=i+1;

  k=(order-2)/4;
  for (i=1; i<=k; i++)
    B.push_back(i);

  for (i=order-k+2; i<=order; i++)
    B.push_back(i);

  int temp;
  for (i=1; i<=ho; i++)
    for (j=1; j<=B.size(); j++)
    {
      temp=mat[i-1][B[j-1]-1];
      mat[i-1][B[j-1]-1]=mat[i+ho-1][B[j-1]-1];
      mat[i+ho-1][B[j-1]-1]=temp;
    }
  i=k;
  j=0;
  temp=mat[i][j]; mat[i][j]=mat[i+ho][j]; mat[i+ho][j]=temp;
  j=i;
  temp=mat[i+ho][j]; mat[i+ho][j]=mat[i][j]; mat[i][j]=temp;
}

int main()
{
  int Order;
  cout<<"Enter the order of square which you wanna: ";
  cin>>Order;
  vector<vector<int> > mat(Order, vector<int> (Order, 0));

  // For order less than 3 is meaningless so printing error
  if (Order<3)
  {
    cout<<" Order Of Square must be greater than 2";
    return -1;
  }

   // For Order is Odd
    if (Order%2==1)
      BuildOddMagicSquare(mat, Order);

   // For Order is Even
   else
   {
    //For Order is Doubly Even Order
    if (Order % 4==0)
      BuildDoublyEvenMagicSquare(mat, Order);
     //For Order is Singly Even Order
    else
      BuildSinglyEvenMagicSquare(mat, Order);
   }


  // Display Results

  for (int i=0; i<Order; i++)
  {
    for (int j=0; j<Order; j++)
    {
      cout<< mat[i][j]<<"  " ;
    }
    cout<<endl;
  }
  return 0;
}

例如,如何在C?

中编写此函数调用
void BuildDoublyEvenMagicSquare(vector<vector<int> > &mat, int Order);

以及vector<vector<int> > &mat的含义是什么?

@Omnifarious

我可以使用这样的东西吗?

 int **mat:
*mat = (int **)malloc(sizeof(int*)*Order);
for (int i=0;i<Order;i++)
mat[i] = (int *)malloc(sizeof(int)*Order);

7 个答案:

答案 0 :(得分:3)

您是否仅限于将项目构建为C项目?如果您正在编写好的C代码(并且它不是C99),您可以毫无困难地将其编译为C ++。如果您可以将其构建为C ++程序,则可以按原样使用该函数。

在这种情况下,你真正需要知道的是你有vector<vector<int> > mat,当你打电话给你的功能时,它就会得到你的结果。然后,您可以将预处理程序指令#include <vector>放在使用它的文件中,并使用using std::vector跟随它,一切都会正常工作。特别是,您可以使用mat[i][j]读取值,就像使用C中的int数组数组一样。

要注意的一点是,您要编写vector<vector<int> >而不是vector<vector<int>>,因为在后者中>>将被视为右移运算符而不是尖括号分隔符。这将在C ++ 0x中修复,当它出现时(x数字现在是严格的十六进制),并且可以在特定的编译器中修复。

或者,编写一个包装函数,该函数接收向量并将其更改为int数组的数组。为方便起见,您可以使用mat.size()mat[i].size()找到向量中的元素数。

答案 1 :(得分:2)

我只想回答问题的最后部分。

vector是C ++标准库中的容器。它就像一个数组,它可以在它满了时自动调整大小。

vector<vector<int> >vectorvector个对象,后者持有int

vector<vector<int> >&是对它的引用。引用类似于指针,但您不使用*来访问实际内容。因此,您将mat“视为”它直接是vector对象,除非它真的别名为另一个实例,因此您对其所做的任何更改都会“反映”并影响调用者可以看到的内容

参考的简单例子:

void add1(int& n) {
    ++n;
}

int main() {
    int num = 5;
    add1(num);
    // num is 6 here
}

答案 2 :(得分:2)

对于问题的最后一部分,在C中,如果你遵循我的其余建议,函数原型将如下所示:

void BuildDoublyEvenMagicSquare(int *mat, int Order);

实际上有几种方法可以做到。这里有一些事情是在C中完成的,所以你不得不采取一种稍微不同的方法。最重要的是C ++向量。 C ++ vector就像一个C数组,但它为您完成所有内存管理。这意味着,例如,拥有一个数组数组相当方便,在C中它只会增加资源管理的麻烦。

C ++声明:

vector<int> varname(5);

大致相当于C声明:

int varname[5];

但是在C ++中你可以这样做:

int randominteger = 7;
vector<int> varname(randominteger);

并且在C中这是非法的,除非你有一个C99兼容的编译器(-std = c99 in gcc):

int randominteger = 7;
int varname[randominteger];

C中不能包含具有可变数量元素的数组,因此您必须求助于callocmalloc并执行自己的内存管理,如下所示:

/* Not that this is not necessary and shouldn't be done (as it's *
 * prone to memory leaks) if you have a C99 compliant compiler.  */

int randominteger = 7;
int *varname = calloc(randominteger, sizeof(int));
if (varname == NULL) {
   /* Die horribly of running out of memory. */
}

在这种情况下,我假设你要将你的数组数组展开成一个长整数的C数组,这个数组足以容纳答案,这样你就可以减少你必须管理的内存位数。为实现此目的,我会在mat = calloc(order * order, sizeof(int));中使用main之类的调用,这也意味着当您在{{1}结束时调用free(mat)时,您必须调用main }}

我还假设您正在展开数组,以便您不再拥有数组数组。这意味着你必须做一些数学运算才能将一行,列索引转换为数组的线性索引。类似于row * order + column

你必须在构建魔术方块的每个函数中重复我为main建议的过程,因为它们每个都创建临时数组以保存在函数末尾消失的东西。 / p>

答案 3 :(得分:0)

C ++向量就像一个C数组。它增加了一些不错的功能,如可选的边界检查,当需要增加大小时自动重新分配等等。

向量&lt; int&gt;大致类似于int []。

向量&lt; vector&lt; int&gt; &GT;就像一个int * [],其中每个int *指向一个数组。它不像是一个二维数组 - 每个内部向量可以有不同的大小。

使用&amp;前缀变量使该变量成为引用。引用就像一个指针,您不必明确取消引用。通过引用传递参数是一种常见的C ++习惯用法,它在许多与C中的指针传递相同的情况下使用。

答案 4 :(得分:0)

vector是一个自动调整大小的数组。所以vector<vector<int>>将是一个int数组的数组,相当于C int*[]&mat是对 mat 的引用,类似于指针(实际上我认为C99支持引用)。但是,在这种情况下,由于传入的值已经是指针,因此不需要它。

因此C中的等价物将是

void BuildDoublyEvenMagicSquare(int*[] mat, int Order); 

答案 5 :(得分:0)

您可以摆脱#includes和'using namespace std'行。现在唯一困难的是你的矢量。这里传递的是一个二维的int数组,这在C语言中很容易。如果你不知道开头的界限,那么很难对它进行调整。这就是为什么矢量太棒了 - 你不需要关心。

对于更一般的C ++到C connversion,我建议你得到一本像“C ++ for C programmers”这样的书,并从索引开始工作。更好的是,从头到尾工作并学习C ++。您可能会发现,如果程序以任何方式复杂化,那么在C ++中使用C语言会有一些非常棘手的事情。祝你好运!!

答案 6 :(得分:0)

Vector几乎是C ++的一个数组。有一些方法可以动态调整向量的大小(不使用realloc()),但除此之外,这几乎就是你所看到的。

如果在参数列表中看到&,则表示“通过引用传递此参数”。在C语言中,例程中的参数是传入的内容的副本,因此如果您修改它们,那么修改不会超出函数范围。但是,如果修改C ++引用参数,则还要修改调用程序用于该参数的变量。

因此,要在C中获得等效的<vector<vector<int>> & mat,您可能会将该参数传递为类似int ** mat[]的内容,并假设用户正在传递指向int数组数组的指针他们希望你继续努力。不同之处在于,在例程中,您的C代码必须使用*mat来获取int数组的数组,而在C ++代码中,它们可以直接使用mat