指针在Linux驱动中的应用

本文目录:

  • 第一部分:什么是指针
  • 第二部分:指针在C中的应用
  • 第三部分:Linux驱动实例中的C指针

什么是指针?

网上有很多关于指针的解释。我参考了深入理解C指针这本书,认为指针是一个传送门,通过这个传送门可以访问指针后面的内存。第二部分讲述为什么这么说。

指针在C中的应用

  • 形参是指针

用值传递数据和用指针传递数据的区别:

先看下面的代码。用指针传递数据时,我们在main函数里调用swapWithPointers函数,传入的变量的地址。

//用指针传递
void swapWithPointers(int* pnum1, int* pnum2) {
int tmp;
tmp = *pnum1;
*pnum1 = *pnum2;
*pnum2 = tmp;
}

int main() {
int n1 = 5;
int n2 = 10;
swapWithPointers(&n1, &n2);
return 0;
}

指针在Linux驱动中的应用_第1张图片

如上图所示,swapWithPointers的程序里,通过访问main函数的内存n1、n2。完成了对函数外部内存的调用。

用值传递时,我们传入的是一个经过复制的整数。

//用值传递
void swap(int num1, int num2) {
int tmp;
tmp = num1;
num1 = num2;
num2 = tmp;
}
int main() {
int n1 = 5;
int n2 = 10;
swap(n1, n2);
return 0;
}

指针在Linux驱动中的应用_第2张图片

如上图所示,同样对数值进行了交换,只不过交换的是swap栈帧上的内存数据,直到函数结束,栈的内存被释放,对于函数外部的数据没有影响。

综上所述,对于形参是指针较为浅显的理解是:我们可以在一个栈帧上访问其他位置的数据。如开头所述,指针更像一个传送门,可以便于我们访问内存。

  • 函数指针

很少见到将一个函数定义为指针类型,但是它也被用到了一些特定的场合(做选择),比如用到switch条件语句。

下文里的代码首先定义了fptrOperation 类型,在select里进行函数选择。在进行编译的时候不用select函数里的放入add和subtract占用内存,仅一个地址就就可以了。当然还是要慎用:处理器可能无法配合流水线做分支预测,可能导致程序的性能下降。

想要了解更多用法可以百度或者翻看我上文里提到的参考书。非科班出身的我感觉对内存和指针写的很清晰。

typedef int (*fptrOperation)(int);

fptrOperation select(char opcode) {
switch(opcode) {
case '+': return add;
case '-': return subtract;
}
}

int evaluate(char opcode, int num1, int num2) {
fptrOperation operation = select(opcode);
return operation(num1, num2);
}

int main()
{

printf("%d\n",evaluate('+', 5, 6));
printf("%d\n",evaluate('-', 5, 6));

}

Linux驱动实例中的C指针

学习Linux驱动的过程里,指针是必不可少的。

形参是指针时:

static ssize_t hello_drv_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{
	int err;
	printk("%s %s line %d\n",__FILE__,__FUNCTION__,__LINE__);
	err = copy_to_user(buf, kernel_buf, MIN(1024,size));
	return MIN(1024,size);
}


//copy_to_user的定义
unsigned long copy_to_user(void __user *to, const void *from, unsigned long n)
{
	if (likely(access_ok(VERIFY_WRITE, to, n)))
		n = __copy_to_user(to, from, n);
	return n;
}

为什么在我们的驱动函数里要用指针传递数据呢?很简单,因为内核提供的API接口是指针的。在调用copy_to_user函数时,发现它的形参就是指针。函数的存储区和内存的存储区在概念上是分离的。只有当我们调用具体的函数时,我们可以将函数和内存里的数据放到同一函数栈上,当执行完时内存回收,啥都没了。

 

参考书:深入理解C指针

如果有什么问题可以在评论留言,一般都会回。这篇文章也会持续更新,对它感兴趣的可以收藏。

你可能感兴趣的:(嵌入式Linux,---------,C语言,---------,指针,Linux,嵌入式,c)