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
原文地址:https://www.cnblogs.com/dzyBK/p/13837895.html