如何最好地处理 C/C++ 中的动态多维数组?

2023-11-21

在 C 和/或 C++ 中操作动态(所有维度直到运行时才知道)多维数组的可接受/最常用的方法是什么。

我正在尝试找到最简洁的方法来完成此 Java 代码的功能:

public static void main(String[] args){
 Scanner sc=new Scanner(System.in);
 int rows=sc.nextInt();
 int cols=sc.nextInt();
 int[][] data=new int[rows][cols];
 manipulate(data);
}

public static void manipulate(int[][] data){
   for(int i=0;i<data.length;i++)
   for(int j=0;j<data[0].length.j++){
         System.out.print(data[i][j]);       
   }    
}

(从 std_in 读取只是为了澄清尺寸直到运行时才知道)。

编辑:我注意到这个问题很受欢迎,尽管它已经很老了。我实际上并不同意投票最高的答案。我认为 C 的最佳选择是使用一维数组,正如 Guge 在下面所说的“你可以分配行colssizeof(int) 并通过 table[row*cols+col] 访问它。”。

C++ 有多种选择,如果您真的喜欢 boost 或 stl,那么下面的答案可能更好,但最简单且可能最快的选择是使用 C 中的一维数组。

如果您想要 [][] 语法,C 和 C++ 中的另一个可行选择是 lillq 在底部的答案是手动构建具有大量 malloc 的数组。


Use 升压::多数组.

正如在您的示例中一样,您在编译时唯一需要知道的是维度数。这是文档中的第一个示例:

#include "boost/multi_array.hpp"
#include <cassert>

int 
main () {
  // Create a 3D array that is 3 x 4 x 2
  typedef boost::multi_array<double, 3> array_type;
  typedef array_type::index index;
  array_type A(boost::extents[3][4][2]);

  // Assign values to the elements
  int values = 0;
  for(index i = 0; i != 3; ++i) 
    for(index j = 0; j != 4; ++j)
      for(index k = 0; k != 2; ++k)
        A[i][j][k] = values++;

  // Verify values
  int verify = 0;
  for(index i = 0; i != 3; ++i) 
    for(index j = 0; j != 4; ++j)
      for(index k = 0; k != 2; ++k)
        assert(A[i][j][k] == verify++);

  return 0;
}

编辑:根据评论中的建议,这是一个“简单”的例子允许您在运行时定义多维数组大小的应用程序,从控制台输入询问。 以下是此示例应用程序的示例输出(使用表示它是 3 维的常量进行编译):

Multi-Array test!
Please enter the size of the dimension 0 : 4

Please enter the size of the dimension 1 : 6

Please enter the size of the dimension 2 : 2

Text matrix with 3 dimensions of size (4,6,2) have been created.

Ready!
Type 'help' for the command list.

>read 0.0.0
Text at (0,0,0) :
  ""

>write 0.0.0 "This is a nice test!"
Text "This is a nice test!" written at position (0,0,0)

>read 0.0.0
Text at (0,0,0) :
  "This is a nice test!"

>write 0,0,1 "What a nice day!"
Text "What a nice day!" written at position (0,0,1)

>read 0.0.0
Text at (0,0,0) :
  "This is a nice test!"

>read 0.0.1
Text at (0,0,1) :
  "What a nice day!"

>write 3,5,1 "This is the last text!"
Text "This is the last text!" written at position (3,5,1)

>read 3,5,1
Text at (3,5,1) :
  "This is the last text!"

>exit

代码中的重要部分是主函数,我们从用户那里获取尺寸并使用以下命令创建数组:

const unsigned int DIMENSION_COUNT = 3; // dimension count for this test application, change it at will :)

// here is the type of the multi-dimensional (DIMENSION_COUNT dimensions here) array we want to use
// for this example, it own texts
typedef boost::multi_array< std::string , DIMENSION_COUNT > TextMatrix;

// this provide size/index based position for a TextMatrix entry.
typedef std::tr1::array<TextMatrix::index, DIMENSION_COUNT> Position; // note that it can be a boost::array or a simple array

/*  This function will allow the user to manipulate the created array
    by managing it's commands.
    Returns true if the exit command have been called.
*/
bool process_command( const std::string& entry, TextMatrix& text_matrix );

/* Print the position values in the standard output. */
void display_position( const Position& position );

int main()
{
    std::cout << "Multi-Array test!" << std::endl;

    // get the dimension informations from the user
    Position dimensions; // this array will hold the size of each dimension 

    for( int dimension_idx = 0; dimension_idx < DIMENSION_COUNT; ++dimension_idx )
    {
        std::cout << "Please enter the size of the dimension "<< dimension_idx <<" : ";
        // note that here we should check the type of the entry, but it's a simple example so lets assume we take good numbers
        std::cin >> dimensions[dimension_idx]; 
        std::cout << std::endl;

    }

    // now create the multi-dimensional array with the previously collected informations
    TextMatrix text_matrix( dimensions );

    std::cout << "Text matrix with " << DIMENSION_COUNT << " dimensions of size ";
    display_position( dimensions );
    std::cout << " have been created."<< std::endl;
    std::cout << std::endl;
    std::cout << "Ready!" << std::endl;
    std::cout << "Type 'help' for the command list." << std::endl;
    std::cin.sync();


    // we can now play with it as long as we want
    bool wants_to_exit = false;
    while( !wants_to_exit )
    {
        std::cout << std::endl << ">" ;
        std::tr1::array< char, 256 > entry_buffer; 
        std::cin.getline(entry_buffer.data(), entry_buffer.size());

        const std::string entry( entry_buffer.data() );
        wants_to_exit = process_command( entry, text_matrix );
    }

    return 0;
}

您可以看到,要加入数组中的元素,非常简单:您只需使用operator(),如以下函数所示:

void write_in_text_matrix( TextMatrix& text_matrix, const Position& position, const std::string& text )
{
    text_matrix( position ) = text;
    std::cout << "Text \"" << text << "\" written at position ";
    display_position( position );
    std::cout << std::endl;
}

void read_from_text_matrix( const TextMatrix& text_matrix, const Position& position )
{
    const std::string& text = text_matrix( position );
    std::cout << "Text at ";
    display_position(position);
    std::cout << " : "<< std::endl;
    std::cout << "  \"" << text << "\"" << std::endl;
}

注意:我在 VC9 + SP1 中编译了这个应用程序 - 只得到了一些容易忘记的警告。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何最好地处理 C/C++ 中的动态多维数组? 的相关文章

  • std::map find 在 C++ 中不起作用[重复]

    这个问题在这里已经有答案了 我使用以下几行创建了一个哈希映射和一个迭代器 std map
  • 地图类容器的专用功能

    我想要专门为矢量和地图之类的容器设计一个函数模板 对于向量 我可以像下面那样做 但我不知道如何才能有一个专门版本的函数 该函数仅用于像地图这样的容器 include
  • 创建一个 int 类型的随机数组。爪哇

    我需要创建一个随机的 int 数组 并按我自己的类对其进行排序 这是我制作数组的地方 public class MyProgram9 public static void main String args int list new int
  • 处理器关联组 C#

    我使用的是 72 核的 Windows Server 2016 我看到有两组处理器 我的 net 应用程序将使用一个或其他组 我需要能够强制我的应用程序使用我选择的组 我看到下面的代码示例 但我无法使其工作 我可能传递了错误的变量 我希望应
  • 没有配置身份验证处理程序来处理该方案

    这是一个非常烦人的问题 我在我的 asp net core 项目上设置 cookie 身份验证 有时会出现此错误 有时不会 没有图案 它只是开始抛出错误 然后突然停止 然后再次开始 例外情况是 InvalidOperationExcepti
  • 以编程方式更新 Wifi 网络

    我正在尝试创建一个程序 当某个 wifi 网络在范围内时 该程序会连接到该网络 即使已经连接到另一个 wifi 也是如此 我在用着简单Wifi https github com DigiExam simplewifi 基本上效果很好 除了在
  • 图片框、双击和单击事件

    我有一个奇怪的问题 我有一个图片框双击事件以及单击事件 问题是即使我双击该控件 也会引发单击事件 如果我禁用单击事件 则双击事件正在工作 这个问题已经在这里讨论过 https stackoverflow com questions 1830
  • MVC BaseController 处理 CRUD 操作

    我想重构我的基本 CRUD 操作 因为它们非常重复 但我不确定最好的方法 我的所有控制器都继承 BaseController 如下所示 public class BaseController
  • 在编译输出中添加程序集绑定 (app.config)

    如果我编译应用程序 则会在输出中自动添加程序集绑定 具体的程序集绑定不在app config在 Visual Studio 中但在创建的应用程序配置中 有什么办法可以检查为什么会自动添加程序集绑定吗 选项AutoGenerateBindin
  • C++:避免​​在重载中将字符串自动转换为布尔值

    我想创建一组方法 这些方法将根据其类型输出具有特殊格式的值 当我这样做时 到目前为止看起来还不错 static void printValue std ostringstream out int value out lt lt value
  • 在 C++ 中,为什么 const 也可以工作时编译器选择非常量函数? [复制]

    这个问题在这里已经有答案了 例如 假设我有一堂课 class Foo public std string Name m maybe modified true return m name const std string Name cons
  • 将两个垂直滚动条相互绑定

    我在控件中有两个 TextBox 并且它们都有两个 VerticalScrollBar 我想在它们之间绑定 VerticalScrollBars 如果一个向上 第二个也会向上等等 如果可以的话我该怎么做 Thanks 不是真正的绑定 但它有
  • 大小为 k 的非连续子序列的最大值的最小值

    在开始之前 我希望这个问题不是重复的 我发现了几个类似的问题 但它们似乎都没有描述完全相同的问题 但如果它是重复的 我会很高兴看到一个解决方案 即使它与我的算法不同 我一直在尝试回答这个问题 https stackoverflow com
  • 批量插入,asp.net

    我需要获取与会员相对应的 ID 号列表 在任何给定时间处理的数量可能在 10 到 10 000 之间 我可以毫无问题地收集数据 解析数据并将其加载到 DataTable 或任何内容 C 中 但我想在数据库中执行一些操作 将所有这些数据插入表
  • 如何处理文件名中的空格

    我正在尝试迭代本地目录中的文件 foreach string name in Directory GetFileSystemEntries path FileAttrtibutes att File GetAttributes name 文
  • 从 SQL 语句中检索元数据(表名)

    我使用的是 Visual Studio 2008 我创建了一个 Winforms 应用程序 并且尝试从 SQL 语句中提取表名 con new SqlConnection connString String queryString Sele
  • ArrayList 有什么问题?

    最近我问了一个关于 SO 的问题 其中提到了可能使用 c ArrayList 来解决问题 有人评论说使用数组列表不好 我想了解更多有关此的信息 我以前从未听说过关于数组列表的这种说法 有人可以带我了解使用数组列表可能出现的性能问题吗 C n
  • Microsoft Visual Studio 2017 中的 wxWidgets 设置

    我花了大约 20 个小时试图弄清楚如何在 Microsoft Visual Studio 2017 中设置 wxWidgets 我遵循 https wiki wxwidgets org Microsoft Visual C 2B 2B Gu
  • C 中的等效 plpgsql 触发器

    我有一个 PostgreSQL 9 0 服务器 并且在某些表上使用继承 因此我必须通过如下触发器模拟外键 CREATE OR REPLACE FUNCTION othertable before update trigger RETURNS
  • 获取线段上最接近另一个点的点[关闭]

    Closed 这个问题需要调试细节 help minimal reproducible example 目前不接受答案 我想找到线段AB上最接近另一个点P的点 我的想法是 Get a1 and b1由直线公式y1 a1x b1 使用 A 点

随机推荐

  • Hamcrest Matchers.contains 匹配器不起作用(?)

    我正在尝试测试集合中是否有一个 toString 方法返回特定字符串的项目 我尝试使用优秀的 Hamcrest 匹配类 通过将 contains 与Matchers hasToString 但不知何故 它Matchers contains即
  • SQLiteException:无法在事务中启动事务(代码 1)

    我在完成 SQLite 事务时遇到问题 并且完全不知道如何完成它 它看起来完全像this bug从2007年开始 我正在创建我的employee表 引用另一个表entity 如下 为简洁起见进行编辑 CREATE TABLE employe
  • 创建StanfordCoreNLP对象时出错

    我已经从以下位置下载并安装了所需的 jar 文件http nlp stanford edu software corenlp shtml Download 我已经包含了五个 jar 文件 斯坦福 pos tagger jar 斯坦福 pso
  • ANDROID_LOOP = true -- 如何避免 MediaPlayer 使用此元数据标签循环音频

    我想用 MediaPlayer 播放设备铃声 但似乎元数据标签 ANDROID LOOP true 设置MediaPlayer忽略该方法的调用设置循环 mMediaPlayer setLooping false 并在任何情况下循环播放音频
  • Python PIPE 到 popen stdin

    我正在尝试类似的事情实时 subprocess Popen 通过 stdout 和 PIPE 但是 我也想将输入发送到正在运行的进程 如果我使用以下命令在单独的线程中启动进程 process subprocess Popen cmd std
  • 比较时,不带键字段的 VB.NET 匿名类型与 C# 匿名类型有何不同?

    我对此感到摸不着头脑 因为我无法理解为什么会发生以下情况 VB NET Dim product1 New With Name paperclips Price 1 29 Dim product2 New With Name papercli
  • npm 安装失败

    首先我要说的是 我几乎没有在终端或使用 Node js 工作的经验 同事去度假了 我正在尝试按照他留下的说明在我们的演示服务器上设置他的应用程序 我可以让所有内容在本地运行 但在安装 socket io 模块的服务器上遇到问题 安装了pyt
  • 产品平面表不会重新索引 - 行大小太大

    当我尝试重新索引产品平面数据时 我得到There was a problem with reindexing process 数据库修复没有帮助 Exception log 文件显示此错误 2011 08 29T11 54 05 00 00
  • IE 10 中的 event.preventDefault

    我正在提交一个表单 并且我想阻止提交操作 直到我执行一些其他操作 例如显示文件上传进度条 我根据诸如此类的问题设置了此代码event preventDefault 函数在 IE 中不起作用 document ready function f
  • 如何在 Twig 日期过滤器中使用时区?

    我正在使用 Twig 和这个日期过滤器 http www twig project org doc templates html date 显然他们正在寻找参数中的 DateTime 实例 看着这个http www php net manu
  • 提要对话框:图片未显示

    我的 Facebook 提要对话框链接正确呈现了对话框页面 但使用图片参数设置的图像未显示 只是表示没有图片的灰线 我已经更改了图片文件和类型几次 但图像仍然不显示 这是代码 share url https www facebook com
  • Python的打印函数在调用时会刷新缓冲区? [复制]

    这个问题在这里已经有答案了 我有以下代码来刷新输出缓冲区 print return 1 sys stdout flush 我可以设置打印函数 以便它在调用时自动刷新缓冲区吗 您可以使用 u 标志以无缓冲模式启动 python 例如 pyth
  • java.lang.NoSuchMethodError: org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont.addNewFamily()

    将 poi 升级到版本并添加来自 apache 站点的 jar 包 但是出现以下错误 java lang NoSuchMethodError org openxmlformats schemas spreadsheetml x2006 ma
  • 将查询字符串解析为数组

    我怎样才能转一个string下面进入array pg id 2 parent id 2 document video 这就是我正在寻找的数组 array pg id gt 2 parent id gt 2 document gt video
  • 泛型函数类型别名

    为什么在 TypeScript 中类型别名不能与泛型函数一起使用 例如 这里 TS 没有将 Identical 类型定义为泛型 type Identical
  • Django ALLOWED_HOSTS 通过 Apache 接受本地 IP

    我正在使用 Apache 提供 Django 应用程序 在 Django 的 settings py 中我有DEBUG False 因此我必须允许一些主机 例如 ALLOWED HOSTS dyndns org localhost 这工作正
  • Keras 自定义损失作为多个输出的函数

    我使用 keras 一个卷积网络 构建了一个自定义架构 该网络有 4 个头 每个头输出不同大小的张量 我正在尝试编写一个自定义损失函数作为这 4 个输出的函数 我之前一直在实施自定义损失 但它要么是每个头的不同损失 要么是每个头的相同损失
  • 在“DELETE FROM table”之后更改 sqlite 文件大小

    我正在使用 sqlite3 文件 首先 我进入了比较大的数据库 文件大小约为100 MB 比我做的 db gt exec DELETE FROM table 并只输入了该数据库的一小部分 但文件大小仍为 100 MB 删除 sqlite 文
  • Android:从回调中获取结果(网络 KOUSH ION)

    对于我的应用程序 我需要从我们的服务器联系我们的 API 该服务器返回一些 JSON 下载 JSON 时 它应该显示一个进度条 我想我应该使用Android的AsyncTask在进行网络操作时处理 GUI 所以我在我的文件中编写了以下内容A
  • 如何最好地处理 C/C++ 中的动态多维数组?

    在 C 和 或 C 中操作动态 所有维度直到运行时才知道 多维数组的可接受 最常用的方法是什么 我正在尝试找到最简洁的方法来完成此 Java 代码的功能 public static void main String args Scanner