• CV学习日志:C语言中数组的深层使用


             以三维数组int aaa[7][8][9]为例来分析。

             首先需要明确的是不管是多少维数组,其内存都是连续分布的。

    1.用数组名表示数组地址

             (1)aaa表示地址且aaa=aaa[0]=aaa[0][0]=&aaa[0][0][0]

             (2)aaa[i]表示地址且aaa[i]=aaa[i][0]=&aaa[i][0][0],且有aaa[0]<aaa[1] <…<aaa[6]

             (3)aaa[i][j]表示地址且aaa[i][j]=&aaa[i][j][0],且aaa[i][0] <aaa[i][2]<…<aaa[i][7]

    2.用数组名计算数组尺寸

             (1)sizeof(aaa)=7*8*9*sizeof(aaa[0][0][0])

             (2)sizeof(aaa[i])=8*9*sizeof(aaa[0][0][0])

             (3)sizeof(aaa[i][j])=9*sizeof(aaa[0][0][0])

    3.数组维度的形象理解

             基于以上分析可知,若要将三维数组aaa看作一栋楼,则应看作一栋共有7层、每层8排、每排9户的楼而不是一栋具有9层、每层8排、每排7户的楼,且第0层应为a[0]而不是a[6],第i层的第0排应是a[i][0]而不是a[i][7],第i层的第j排的第0户应是a[i][j][0]而不是a[i][j][8]

    4.多组数组与OpenCV::Mat

             基于aaa定义体阵:int szs[3]={7,8,9}; Mat_<int> AAA3D(3, szs, aaa);

             则aaa与AAA3D相对应:aaa[i][j][k]==AAA3D(i,j,k)、aaa[i][j]==AAA3D.ptr<i,j>、aaa[i]==AAA3D.ptr<i>

             这也同时说明了多维的OpenCV::Mat的每个维度与访问索引的对应关系。

             以下样例代码,依赖于C++14、OpenCV4.x和Spdlog。

     1 #include <opencv2/opencv.hpp>
     2 #include <spdlog/spdlog.h>
     3 using namespace std;
     4 using namespace cv;
     5 
     6 class AboutCArr
     7 {
     8 public:
     9     template<typename invalidTP = char> static string cvarr2str(InputArray v) { Ptr<Formatted> fmtd = cv::format(v, Formatter::FMT_DEFAULT); string dst; fmtd->reset(); for (const char* str = fmtd->next(); str; str = fmtd->next()) dst += string(str); return dst; }
    10     static void TestMe(int argc = 0, char** argv = 0)
    11     {
    12         //1.
    13         int aaa[2][3][4];
    14 
    15         Mat_<int> AAA1D(1, 24, (int*)aaa);
    16         randu(AAA1D, 10, 99);
    17 
    18         //2.
    19         spdlog::set_pattern("%v");
    20         string str = fmt::format("aaa_addr:{}   aaa_bytes:{}", (void*)aaa, sizeof(aaa));
    21 
    22         //3.
    23         str += fmt::format("
    	aaa[0]_addr:{}   aaa[0]_bytes:{}", (void*)aaa[0], sizeof(aaa[0]));
    24         str += fmt::format("
    		aaa[0][0]_addr:{}   aaa[0][0]_bytes:{}		", (void*)aaa[0][0], sizeof(aaa[0][0])); for (int k = 0; k < 4; ++k) str += fmt::format("	{}", aaa[0][0][k]);
    25         str += fmt::format("
    		aaa[0][1]_addr:{}   aaa[0][1]_bytes:{}		", (void*)aaa[0][1], sizeof(aaa[0][1])); for (int k = 0; k < 4; ++k) str += fmt::format("	{}", aaa[0][1][k]);
    26         str += fmt::format("
    		aaa[0][2]_addr:{}   aaa[0][2]_bytes:{}		", (void*)aaa[0][2], sizeof(aaa[0][2])); for (int k = 0; k < 4; ++k) str += fmt::format("	{}", aaa[0][2][k]);
    27 
    28         str += fmt::format("
    	aaa[1]_addr:{}   aaa[1]_bytes:{}", (void*)aaa[1], sizeof(aaa[1]));
    29         str += fmt::format("
    		aaa[1][0]_addr:{}   aaa[1][0]_bytes:{}		", (void*)aaa[1][0], sizeof(aaa[1][0])); for (int k = 0; k < 4; ++k) str += fmt::format("	{}", aaa[1][0][k]);
    30         str += fmt::format("
    		aaa[1][1]_addr:{}   aaa[1][1]_bytes:{}		", (void*)aaa[1][1], sizeof(aaa[1][1])); for (int k = 0; k < 4; ++k) str += fmt::format("	{}", aaa[1][1][k]);
    31         str += fmt::format("
    		aaa[1][2]_addr:{}   aaa[1][2]_bytes:{}		", (void*)aaa[1][2], sizeof(aaa[1][2])); for (int k = 0; k < 4; ++k) str += fmt::format("	{}", aaa[1][2][k]);
    32         spdlog::info(str);
    33 
    34         //4.
    35         spdlog::info("AAA1D: {}", cvarr2str<>(AAA1D));
    36 
    37         //5.
    38         spdlog::info("Conclusions:");
    39         spdlog::info("	1.Equivalent address: aaa = aaa[0] = aaa[0][0], aaa[i] = aaa[i][0]");
    40         spdlog::info("	2.Automatic length: sizeof(aaa), sizeof(aaa[i]), sizeof(aaa[i][j])");
    41         spdlog::info("	3.Block memory operations(e.g memset and memcpy) are workable for array names: aaa, aaa[i], aaa[i][j]");
    42 
    43         //6.
    44         str = "
    
    AAA3D: [";
    45         int szs[3] = { 2, 3, 4 };
    46         Mat_<int> AAA3D(3, szs, (int*)aaa);
    47         for (int i = 0; i < szs[0]; ++i) for (int j = 0; j < szs[1]; ++j) for (int k = 0; k < szs[2]; ++k) str += fmt::format("{}, ", AAA3D(i, j, k));
    48 
    49         //7.
    50         str += fmt::format("
    	AAA3D.ptr<int>(0):{}", (void*)AAA3D.ptr<int>(0));
    51         str += fmt::format("
    		AAA3D.ptr<int>(0, 0):{}		", (void*)AAA3D.ptr<int>(0, 0)); for (int k = 0; k < 4; ++k) str += fmt::format("	{}", AAA3D.ptr<int>(0, 0)[k]);
    52         str += fmt::format("
    		AAA3D.ptr<int>(0, 1):{}		", (void*)AAA3D.ptr<int>(0, 1)); for (int k = 0; k < 4; ++k) str += fmt::format("	{}", AAA3D.ptr<int>(0, 1)[k]);
    53         str += fmt::format("
    		AAA3D.ptr<int>(0, 2):{}		", (void*)AAA3D.ptr<int>(0, 2)); for (int k = 0; k < 4; ++k) str += fmt::format("	{}", AAA3D.ptr<int>(0, 2)[k]);
    54 
    55         str += fmt::format("
    	AAA3D.ptr<int>(1):{}", (void*)AAA3D.ptr<int>(1));
    56         str += fmt::format("
    		AAA3D.ptr<int>(1, 0):{}		", (void*)AAA3D.ptr<int>(1, 0)); for (int k = 0; k < 4; ++k) str += fmt::format("	{}", AAA3D.ptr<int>(1, 0)[k]);
    57         str += fmt::format("
    		AAA3D.ptr<int>(1, 1):{}		", (void*)AAA3D.ptr<int>(1, 1)); for (int k = 0; k < 4; ++k) str += fmt::format("	{}", AAA3D.ptr<int>(1, 1)[k]);
    58         str += fmt::format("
    		AAA3D.ptr<int>(1, 2):{}		", (void*)AAA3D.ptr<int>(1, 2)); for (int k = 0; k < 4; ++k) str += fmt::format("	{}", AAA3D.ptr<int>(1, 2)[k]);
    59         spdlog::info(str);
    60     }
    61 };
    62 
    63 int main(int argc = 0, char** argv = 0) { AboutCArr::TestMe(argc, argv); return 0; }
    View Code
  • 相关阅读:
    设计模式学习笔记--迭代器模式
    设计模式学习笔记--组合模式
    设计模式学习笔记--备忘录模式
    Asp.Net Core IdentityServer4 中的基本概念
    Asp.Net Core 中间件应用实践中你不知道的那些事
    Asp.Net Core Filter 深入浅出的那些事-AOP
    ASP.NET CORE 内置的IOC解读及使用
    ASP.NET CORE 管道模型及中间件使用解读
    ASP.NET CORE 启动过程及源码解读
    Linux +Docker +Nginx 部署代理转发初探
  • 原文地址:https://www.cnblogs.com/dzyBK/p/13837895.html
Copyright © 2020-2023  润新知