记得刚开始接触caffe,yolo的darkent等框架时,学习框架源码的过程中,最大的感触就是明明我学过C,C++,为什么这种纯靠C,C++写的框架中用到的好多语法我都没见过?慢慢接触下来发现,C语言中还是有很多有意思的语法,比如template(模板),数组指针等等。这些知识点并没有在谭浩强老师的书里出现过。本文主要给大家介绍下数组指针。
如下代码段,展示了几种初始化数组的方式。还特别提到了一个针对于数组名的要点,即:数组名是数组首元素地址,而对数组名取地址则是整个数组的地址。
void main1()
{
int a[] = {1, 2};
int b[100] = {1, 3};
int c[200] = {0}; //编译的时候 就已经确定 所有的值 为零
memset(c, 0, sizeof(c)); //通过显示的方式 重置内存块
//对一维数组 C语言的编译器规定:
//c是数组首元素的地址 c+1 步长 4个字节
//&c 是整个数组的地址 //&c+1 步长 200*4
return ;
}
在学习数组时,一个核心问题为:我们要认定数组也是一种类型,所谓类型就是说这是固定大小内存块的别名。C语言中将该别名定义为int [len],因此我们可以用下述的typedef来定义一个数组类型,并用该类型声明对应的数组。
void main2()
{
typedef int (MyArrayType)[5]; //定义了一个数据类型 数组数据类型
int i = 0;
MyArrayType myArray; //int myArray[5];
for (i=0; i<5; i++)
{
myArray[i] = i+1;
}
for (i=0; i<5; i++)
{
printf("%d ", myArray[i]);
}
printf("myArray代表数组首元素的地址 myArray:%d myArray+1:%d \n", myArray, myArray+1);
printf("&myArray代表整个数组的地址 &myArray:%d &myArray+1:%d \n", &myArray, &myArray+1);
return ;
}
我们明确了数组是一种数据类型,并初步了解了如何定义一个数组类型后,基于上述方式我们可以通过三种方法来定义数组指针变量。
第一:用数组类型定义数组指针类型
第二:通过数组类型直接定义数组指针类型
第三:直接定义数组指针类型
第一种方式,用数组类型来定义数组指针变量,如下代码所示,先定义一个数组类型,再像最常规的方式一样定义一个数组指针类型。下述代码中第一句话表示你的是一个指针数组,一种二维指针的模型,列在此处是为了和数组指针作区别,希望读者们能够理解其中的区别。
void main_solution1()
{
char *Myarray[] = {"a", "bb", "ccc"}; //指针数组
//数组指针 用一个指针 来指向一个数组
typedef int (MyArrayType)[5]; //定义了一个数据类型 数组数据类型
int i = 0;
MyArrayType myArray; //int myArray[5]; //用类型定义变量
MyArrayType *pArray; //定义一个指针变量 这个指针变量 指向一个数组
int myArray2[5]; //相当于一级指针
pArray = &myArray2; //相当于2级指针
for (i=0; i<5; i++)
{
(*pArray)[i] = i+1;
}
for (i=0; i<5; i++)
{
printf("%d ", (*pArray)[i]);
}
return ;
}
第二种方式,通过结合数组的定义和数组指针的定义,直接一步到位定义一个数组指针类型,用该类型即可定义数组指针。
void main_solution2()
{
//定义声明一个数组指针类型
typedef int (*PArrayType)[5];
PArrayType pArray; //告诉编译器 给我分配一个指针变量
int c[5];
int i = 0;
pArray = &c;
for (i=0; i<5; i++)
{
(*pArray)[i] = i + 1;
}
for (i=0; i<5; i++)
{
printf("%d ", (*pArray)[i]);
}
return ;
}
第三种方式,上述两种方式都通过了数组类型来定义数组指针变量,而第三种方式是直接定义一个数组指针变量的方式。
void main_solution3()
{
int (*pMyArray)[5]; //直接定义一个指向数组的 数组指针变量
int c[5];
int i = 0;
pMyArray = &c;
for (i=0; i<5; i++)
{
(*pMyArray)[i] = i + 1;
}
for (i=0; i<5; i++)
{
printf("%d ", (*pMyArray)[i]);
}
printf("hello...\n");
system("pause");
return ;
}
总结来说,C语言中还是有相当一部分奇怪的语法,我们不一定要全部掌握,但是一旦你在平时的工作学习中遇到了,就一定要把对应的知识点挖懂,这样才会有成长~ 最后插一句,caffe代码里全是模板,而darknet源码里全是指针。感觉能把C语言用的这么溜,写出一个深度学习框架的大牛是真的牛。