学习深度学习框架源码有感 | 我以为我会C语言

记得刚开始接触caffe,yolo的darkent等框架时,学习框架源码的过程中,最大的感触就是明明我学过C,C++,为什么这种纯靠C,C++写的框架中用到的好多语法我都没见过?慢慢接触下来发现,C语言中还是有很多有意思的语法,比如template(模板),数组指针等等。这些知识点并没有在谭浩强老师的书里出现过。本文主要给大家介绍下数组指针。

1.数组基础概念

如下代码段,展示了几种初始化数组的方式。还特别提到了一个针对于数组名的要点,即:数组名是数组首元素地址,而对数组名取地址则是整个数组的地址。


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 ;
}
2.三种数组指针的用法

我们明确了数组是一种数据类型,并初步了解了如何定义一个数组类型后,基于上述方式我们可以通过三种方法来定义数组指针变量。

第一:用数组类型定义数组指针类型
第二:通过数组类型直接定义数组指针类型
第三:直接定义数组指针类型

第一种方式,用数组类型来定义数组指针变量,如下代码所示,先定义一个数组类型,再像最常规的方式一样定义一个数组指针类型。下述代码中第一句话表示你的是一个指针数组,一种二维指针的模型,列在此处是为了和数组指针作区别,希望读者们能够理解其中的区别。

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语言用的这么溜,写出一个深度学习框架的大牛是真的牛。

发布了233 篇原创文章 · 获赞 187 · 访问量 40万+

猜你喜欢

转载自blog.csdn.net/qiu931110/article/details/94858027