【问题标题】:Program crashes when converting C++ code to C [closed]将 C++ 代码转换为 C 时程序崩溃 [关闭]
【发布时间】:2014-10-19 09:58:49
【问题描述】:

我遇到了一个有趣的算法,但我很难用 C 语言实现。

我确实在 C++ 中找到了它的代码,但我尝试将 C++ 代码转换为 C,但程序崩溃了。

C++ 代码如下:

int BalancedPartition ( int a[] , int n ){

    int sum = 0;
    for( int i = 0 ; i < n ; i++)
        sum += a[i];

    int *s = new int[sum+1];

    s[0] = 1;
    for(int i = 1 ; i < sum+1 ; i++)    s[i] = 0;

    int diff = INT_MAX , ans;

    for(int i = 0 ; i < n ; i++)
    {
        for(int j = sum ; j >= a[i] ; j--)
        {
            s[j] = s[j] | s[j-a[i]];
            if( s[j] == 1 )
            {
                if( diff > abs( sum/2 - j) )
                {
                    diff = abs( sum/2 - j );
                    ans = j;
                }

            }
        }
    }
    cout<< ans << " " << sum-ans<< endl; //two balanced partitions

    return min( ans , sum-ans );
}

我的(部分)C 代码如下:

double WeightDifference(int *a, int n)
{
    int sum = 0;



    for (int i = 0; i < n; i++){
        sum += *a[i];

    }

    const sizeOfS = sum + 1;
    int *s[32467];

我们将不胜感激。

【问题讨论】:

  • int *s[32467]; 创建一个巨大的整数指针数组。你可能想要int s[32467];。 C++ 语法是因为new.
  • C 和 C++ 代码中的数组行为相同,所以它只是 sum += a[i]。使用额外的 * 取消引用并不能满足您的要求。
  • *a[i]; 不需要*
  • 大家好,感谢您的回复,稍后代码也会崩溃。你们中的任何人都可以上传C代码吗?
  • 除了通过流输出和使用new 创建数组之外,您的 C++ 代码应该与 C 代码一样好。如果你使用 malloc/free 组合而不是 new 或可变长度数组并使用 printf 而不是那些讨厌的 &lt;&lt;s,你应该没问题。

标签: c++ c algorithm


【解决方案1】:

sum += *a[i];

肯定是错误的,因为 a 是 a 指针,并且您已经使用 [] 运算符访问了它的元素。删除不需要的取消引用(* 运算符)。

int *s[32467];

您的意思可能是创建一个整数数组而不是指向整数的指针数组。

int s[32467];

【讨论】:

  • 有效。为此欢呼
【解决方案2】:

在 C 程序中不能使用循环

for(int i=0....),

先初始化一个变量

int i=0; 

然后继续你的循环:

for( i=0; i<n; i++ ) {...whatever you want to do in the loop...} 

【讨论】:

  • 在 C99 中,您可以。在循环中使用之前,也不需要初始化i
  • 这不会导致崩溃。
【解决方案3】:

“new”运算符仅适用于 C++,因此您需要将其替换为 calloc:

int *s = calloc(sum+1,sizeof(int));

而不是

int *s = new int[sum+1];

"cout" 是 C++ 特有的对象,所以用 printf 替换它:

printf("%d %d \n",ans,sum-ans);  /* two balanced partitions */

而不是

cout<< ans << " " << sum-ans<< endl; // two balanced partitions 

C 编译器需要知道在哪里可以找到 calloc 和 INT_MAX 所以这些 包括是必要的:

/* for malloc or calloc */
#include <stdlib.h>
/* for INT_MAX */
#include <limits.h>

您可能需要添加一个 min 函数:

int min(int a, int b)
{
  if (a < b) 
    return a;
  else
    return b;
}

如果您不使用 C99 编译器,如另一个答案中所述, for 循环中的索引变量需要在函数顶部而不是在 for 循环中声明。如果您的编译器较旧并且拒绝它们与代码混合,您可能还需要将所有变量声明移到顶部。

【讨论】:

  • 如果a[] 的元素是偶数,我的 C 程序会给出错误的输出。你知道解决这个问题吗?
  • +1 为您的答案。如果对偶数元素问题进行了排序,将为接受的答案打勾
  • @user3353723 提供的 C++ 代码在编译为 C++ 并输入偶数时是否给出正确答案?
  • 不,不是。你知道怎么解决吗?
  • 代码的用途是什么?输入的整数数组是否应该排序?
【解决方案4】:

原始代码很少使用 C++ 特定的语法或语义,并且很容易被重写为 C 代码。您的错误是 s 引用了 int 类型的动态数组,而您已将其替换为 int* 类型的自动数组。

要直接翻译,请替换:

int* s = new int[sum+1] ;

int* s = malloc( sizeof(int) * (sum + 1) ) ;

另外,由于函数接口没有任何特定于 C++ 的内容,并且假设它没有重载,您可以简单地将原始代码编译为带有 C 链接的 C++:

extern "C" int BalancedPartition ( int a[] , int n )
{
   ...

在 .cpp 文件中编译为 C++,然后链接到您的 C 代码,该函数可以按原样调用。

另一种解决方案是保留现有 C++ 代码原样,只需将 C 代码重新编译为 C++。大多数格式良好的 C 代码将编译为 C++ 而不做任何更改,或者比尝试将 C++ 转换为 C 的更改更少。在许多情况下,将 C 代码编译为 C++ 也会发现错误,并且 C++ 中的类型检查更严格。

最好将 C 与试图重写它的 C++ 互操作,尤其是因为 C++ 是一种更大的语言,许多简单的结构在呈现为 C 时会变得丑陋和复杂。

【讨论】:

  • 如果 a[] 的元素是偶数,我的 C 程序会给出错误的输出。你知道要解决这个问题吗?+1 来回答你的问题。
  • 嗨,klavourord,我不能将它编译为 C++,因为我们被告知只为我们的工作项目包含 C 代码。
  • 回答您在评论中发布的次要问题可能不合适。您可能应该使用您的实际代码发布一个进一步的问题(由于您尚未发布完整版本,因此信息不足)。但是,我强烈建议您使用工具链的调试器来单步执行代码并观察每一步的变量状态以确定问题所在 - 这通常是一种比在 SO 或论坛上发布的更高效的调试方法。
  • @user3353723 :我会告诫不要将来源或质量未知的“找到的代码”用作学术作业的“资源”。除了抄袭问题,您可能还没有能力确定代码的质量,并且可能无法在您提交的文件中解释或证明其设计(即您会被抓住!)。
  • @user3353723 :在现实世界中,没有人会任意限制实现。问题中应提及出于学术原因对您施加的任何解决方案限制,因为从表面上看,您的解决方案(将代码转换为 C)是最不理想的选择。此外,人们需要知道这是否本质上是一个“家庭作业”问题,以避免“为你做” - 你也可能被抓住 - 谷歌搜索“BalancedPartition”已经将此问题作为第一个命中,任何明智的导师会在 Google 上搜索“你的工作”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-18
  • 2011-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多