Chinaunix首页 | 论坛 | 博客
  • 博客访问: 194889
  • 博文数量: 46
  • 博客积分: 1355
  • 博客等级: 中尉
  • 技术积分: 336
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-02 16:20
文章分类

全部博文(46)

文章存档

2017年(2)

2014年(12)

2012年(1)

2011年(5)

2010年(26)

我的朋友

分类: 嵌入式

2010-05-11 20:31:26

globalmem两个设备问题的讨论(同时也是指针的好文章)
些文章很好的回答了,scull中的问题。本例子来自《linux设备驱动开发详解》
看到globalmem的两个设备的程式的时候发现不太懂,遂搜索出论坛里面的一个话题,感觉讲得很不错。而且对指针方面的知识加深了理解,讨论内容如下:
====================================华丽的分割线=================================
LZ:
 
 

支持两个globalmem设备的globalmem驱动

struct globalmem_dev 
{ 
  struct cdev cdev; /*cdev结构体*/ 
  unsigned char mem[GLOBALMEM_SIZE]; /*全局内存*/ 
};

struct globalmem_dev *globalmem_devp; /*设备结构体指针*/


/*设备驱动模块加载函数*/
int globalmem_init(void)
{
  int result;
  dev_t devno = MKDEV(globalmem_major, 0);

  /* 申请设备号*/
  if (globalmem_major)
    result = register_chrdev_region(devno, 2, "globalmem");
  else /* 动态申请设备号 */
  {
    result = alloc_chrdev_region(&devno, 0, 2, "globalmem");
    globalmem_major = MAJOR(devno);
  } 
  if (result < 0)
    return result;
    
  /* 动态申请2个设备结构体的内存*/
  globalmem_devp = kmalloc(2*sizeof(struct globalmem_dev), GFP_KERNEL);
  if (!globalmem_devp) /*申请失败*/
  {
    result = - ENOMEM;
    goto fail_malloc;
  }
  memset(globalmem_devp, 0, 2*sizeof(struct globalmem_dev));
  
  globalmem_setup_cdev(&globalmem_devp[0], 0); 
  globalmem_setup_cdev(&globalmem_devp[1], 1);
  return 0;

  fail_malloc: unregister_chrdev_region(devno, 2);
  return result;
}

static void globalmem_setup_cdev(struct globalmem_dev *dev, int index)
{
...
}

为什么引用这两个设备的地址时用的是&globalmem_devp[0]&globalmem_devp[1]??
1.globalmem_devp本身就是指针,引用应该是globalmem_devp啊?为什么还带地址符?
2.没有定义globalmem_devp是数组指针,为什么用了[0][1]??

==============================华丽的分割线=============================

回复1:

 

int *a; a是指针变量,存放着地址
int a[]; a是数组名,但数组名a也代表数组首元素的地址,那么a能够正确引用为一个指针变量,即a指向数组a[]的首元素,就是说:int *a;那么一旦它指向一个int型数组,则数组名也可以是a,引用数组a的元素可以用a[0]&a[0]就表示第一个单元里的int型数据所在的地址。

所以,我们得到结论,定义一个指针变量,一旦它指向一个数组的首元素,那么首元素的地址可以用&指针变量名[0]来表达;第n个元素的地址可以用&指针变量名[n-1]来表达。

但是有一个问题,在int a[]后,没有指明几个单元内容,内存怎么分配?这种写法是否错误??
经检验,编译错误
那就是说只能把int *a;看作是int a[];现实中不能这么写


编一个例子,验证一下
#include "stdio.h"

int main()
{
        char *a="i love you!";
        printf("a[0]=%c a[1]=%c a[2]=%c\n",a[0],a[1],a[2]);
        printf("a=%x &a[0]=%x &a[2]=%x\n",a,&a[0],&a[2]);
}
编译,运行:
a[0]=i a[1]= a[2]=l
a=80484b0 &a[0]=80484b0 &a[2]=80484b2

这里要强调的是:C语言中没有字符串变量,字符串常量的保存是通过字符数组来实现的。所以指针a指向的是一个字符数组。

所以:
struct globalmem_dev *globalmem_devp; /*设备结构体指针*/


struct globalmem_dev  globalmem_devp[]; 等价。

所以就有了:
globalmem_setup_cdev(&globalmem_devp[0], 0); 
globalmem_setup_cdev(&globalmem_devp[1], 1);

==============================华丽的分割线=============================

回复2:

 

char **a={"hello1","hello2","hello3"};
可以这样用的吧?
那就可以这样用
*a[0]="hello1";
*a[1]="hello2";
*a[2]="hello3";
也就是说,可以这样
char *a={"hello1","hello2","hello3"};

&a[0]="hello1";
&a[1]="hello2";
&a[2]="hello3";
同理,赋值指向的话更没有问题了

转自:http://blog.chinaunix.net/u3/102839/showart_2022717.html
阅读(1979) | 评论(0) | 转发(1) |
0

上一篇:MMU

下一篇:linux内核wait_queue分析

给主人留下些什么吧!~~