C声明变量的用法体现C++封装思想
来源:互联网 发布:考驾照模拟软件 编辑:程序博客网 时间:2024/05/29 18:43
在linux2.6.10中看到这样一些代码;
/mm/slab.c中定义了struct kmem_cache_s{......};
而/include/linux/slab.h中又作了如下定义:typedef struct kmem_cache_s kmem_cache_t;内核其他地方又引用
的都是“kmem_cache_t”,且引用的头文件都是/linux/slab.h,问题由此来了,以前编译一些文件,都是直接在.h文件中
定义一个类型(结构体什么的),还没碰到过用typedef 声明一个类型,而在与.h文件名相同的.c文件下定义,别的文件通
过include此头文件来声明一个变量。这跟以前有什么区别呢?在fed10下做个试验:
/*myprintf.c*/
#include<stdlib.h>
struct kmem_cache
{
int i;
int j;
} ;
/*myprintf.h*/
#ifndef _MYPRINTF_H_
#define _MYPRINTF_H_
typedef kmem_cache kmem;
#endif
/*test.c*/
#include"myprintf.h"
int main()
{
kmem men;
men.i=2;
men.j=3;
printf("%d<--->%d/n",men.i,men.j);
return 0;
}
编译下 gcc -Wall -o test test.c myprintf.c
test.c:在函数‘main’中;
test.c:4:错误:‘men’的存储大小未知
test.c:4:警告:未使用的变量‘men’
ok,不出所料,出错了。。。看来有新东西可以发现了,把.c文件声明的类型放到.h文件中去,编译通过,以前的写法看来
是没错的,但linux上这种写法有什么用处呢?继续搜索内核代码的声明,发现其他文件声明都是kmem_cache_t *cache
之类的,声明的都为此类型的指针变量,为什么声明都是指针呢?而不是某个变量?原来指针变量本身也是有存储空间来存
放它的,要不指针变量一旦变化,那它的值存哪呢?而且存储空间是固定的,有疑问的可以自己验证下,代码如下:
#include<stdio.h>
int main()
{
int *p1;
char *p2;
short *p3;
printf("%d,%d,%d",sizeof(p1),sizeof(p2),sizeof(p3));
return 0;
}
32机指针变量所占的存储空间固定占4字节,所以gcc编译器就不需要检查它的存储大小了,直接分配4字节空间,并标明空
间放的内容是kmem类型的,如果是声明变量的话,编译器只能找到.h文件中的类型声明,而.h文件却只有个typedef定义,
无法得知此类型所占存储空间大小,所以报错:test.c:4:错误:‘men’的存储大小未知。声明个指针有什么好处呢?继续
查找代码,发现指针的值都是通过调用函数kmem_cache_t *kmem_cache_create()的返回值进行赋值,此函数在slab.h
中是有声明的。更改测试代码:
在/*myprintf.c*/文件中加入
kmem* kmem_create(int a,int b)
{
kmem *pa = (kmem*)malloc(sizeof(kmem));/*为指针申请一个kmem大小的内存空间*/
pa->i=a;
pa->j=b;
return pa;
}
在/*myprintf.h*/
kmem *kmem_create(int,int);
修改/*test.c*/
#include"myprintf.h"
int main()
{
kmem men;
int a,b;
a=2;b=2;
men=kmem_create(a,b);
printf("%d<--->%d/n",men->i,men->j); /*注意这行*/
return 0;
}
兴奋的编译下,gcc出新错误了;
test.c:在函数‘main’中
test.c:8:错误:men指向不完全类型的指针
由此看来这种类型声明的指针是不允许访问类型里面的成员,它只能做为一个单纯的指针,送给给类型定义下的.c文件下的处
理函数进行处理。类型的成员对外是不透明,封闭的,.c文件只给提供功能接口函数,提供所需要的功能就OK了,这跟C++
里面类的封装思想很相似。
最终的测试代码如下:
/*myprintf.c*/文件
#include<stdlib.h>
struct kmem_cache
{
int i;
int j;
} ;
kmem* kmem_create(int a,int b)
{
kmem *pa = (kmem*)malloc(sizeof(kmem));/*为指针申请一个kmem大小的内存空间*/
pa->i=a;
pa->j=b;
return pa;
}
int kmem_add(kmem*pa)
{
return pa->i+pa->j;
}
/*myprintf.h*/文件
#ifndef _MYPRINTF_H_
#define _MYPRINTF_H_
typedef kmem_cache kmem;
kmem*kmem_create(int,int);
int kmem_add(kmem*);
#endif
/*test.c*/文件
#include"myprintf.h"
int main()
{
kmem men;
int a,b;
a=2;b=2;
men=kmem_create(a,b);
a=kmem_add(men);/*新加入的行*/
printf("%d /n",a);
return 0;
}
编译下,成功通过生成test执行程序,运行程序结果正确!
此外还想到另外一个问题,指针变量本身所占空间的问题。例如声明一个int型指针变量int *pa; 存储pa变量的空间应该
有个地址给指明,指针变量所占空间是4个字节,可空间返的地址只有一个字节空间,明显不等,我们都知道32位地址总线
指向的存储空间是2^32字节空间,每个32bit的地址占一个字节存储空间,所以指针所占空间返回的地址应该是个首地址,
它应该占用后3位地址。因此可以这样想象 当声明一个指针变量时,指针变量的值就是个32bit的值,固定占4字节空间,编
译器会分配4个字节的空间,并把第一个字节空间的地址当成存储指针变量本身的空间地址;当声明一个其他类型变量(如整
型变量,结构体变量)时,编译器会计算整型或结构体所占空间大小,并分配出的类型大小的空间,同样把第一个字节空间的
地址当成存储此变量本身的空间地址。呵呵,有点绕口。。。
- C声明变量的用法体现C++封装思想
- C语言变量声明加冒号的用法
- C语言变量声明加冒号的用法
- C语言变量声明加冒号的用法
- C语言变量声明加冒号的用法
- C语言变量声明加冒号的用法
- C语言变量声明加冒号的用法,位域
- C语言变量声明加冒号的用法
- C语言变量声明加冒号的用法
- C语言变量声明加冒号的用法
- C语言变量声明加冒号的用法
- C语言 变量的声明
- 【C/C++】变量的定义与声明
- c变量声明问题
- c语言变量声明
- 【C++】变量声明
- C语言变量声明
- C中变量的定义?声明?
- 另一种实现 Fruit Ninja 里刀光效果的方法
- 我迷茫了
- 显示桌面图标丢失
- 小数的阶乘 代码
- Java中的中文乱码产生原理
- C声明变量的用法体现C++封装思想
- VC++ MFC socket编程
- Delphi格式化函数Format、FormatDateTime和FormatFloat
- 程序员的自我修养系列之一
- Flex和.NET协同开发利器FluorineFx--部署
- css position属性
- mysql 字符编码
- SqlBulkCopy类数据导入
- 什么是软件架构