Chinaunix首页 | 论坛 | 博客
  • 博客访问: 151904
  • 博文数量: 20
  • 博客积分: 1515
  • 博客等级: 上尉
  • 技术积分: 305
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-14 10:06
文章分类

全部博文(20)

文章存档

2011年(2)

2010年(4)

2009年(14)

我的朋友

分类: C/C++

2009-05-16 01:12:35

0515 学习笔记

第三章分析C语言的声明

一、结构

       1) 结构就是一种把数据组合在一起的数据结构,结构的语法:

   struct { 内容....}

   结构的内容可以是任何其它数据声明,单个数据项目、数组、其它结构、指针等。

       可以在结构的定义后面跟一些变量名,表示这些变量的类型就是这个结构,例如:

              struct {内容..} plum,pear;

       另外还可以在struct关键字后面加一个可选的结构标签

              struct fruit_tag{内容...} plum,pear;

   因些通常所见的结构形式是:

              struct 结构标签(可选){

                     类型1 标识符1

                     类型2 标识符2;

                     ....

                     }变量定义(可选);

       2)最好把结构的声明和变量定义分开:

              struct veg { int weight ,price_per_lb;}

              struct veg onion,radish,turnip;

        这样使代码看上去容易容易理解一些,而不是这些难以理解的代码:

              struct veg{int weight,price_per_lb;} onion,radish,turnip;

       3)结构和参数传递问题

              参数在传递过程中首先尽可能地存放到寄存器中(追求速度)。但int型变量跟一个只包含int 型成员的变量s 在参数传递时的方式可能完全不同。一个int 参数一般会被传递到寄存器中,而结构参数则很可能被传递到堆栈中.

       4)在结构中放置数组,这样就可以用赋值语句来拷贝整个数组,以传值调用的方式把它传递到数,或者把它作为函数的返回类型

              struct s_tag { int a[100];}

              struct s_tag orange,lime,lemon;

              struct s_tag twofold(struct s_tag s){

                     int j;

                     for(j =0; j < 100 ;j++) s.a[j] *=2;

                     return s

              }

              main(){

                     int i;

                     for(i=0;i< 100 ;i++) lime.a[i] *=1;

                     lemon = twofold(lime);

                     orange = lemon;

              }

二、关于typedef

       1)typedef 是一种声明形式:它为一种类型引入新的名字,而不是为变量分配空间。在某些方面,typedef类似于宏文本替换(但也一个关键性的区别)

       2)typedef 可以用于简洁的表示指向其他东西的指针。典型的例子是signal()原型的声明

              void (*signal(int sig,void(*func)(int)))(int);

             如果按照平常的方法去分析这个声明会比较吃力,现在用typedef代替一通用部分来帮助理解:

              typedef void(*ptr_to_func)(int)//它表示ptr_to_func是一个函数指针,该函数接受一个int参数,返回值为void;

              ptr_to_func signal(int,ptr_to_func);

              //表示signal是一个函数,它接受两个参数,一个是int,另一个是ptr_to_func,返回值是ptr_to_func

       3)使用typedef要注意的地方

              可以把几个声明器放到一个声明中去。但这样会变得难以理解,如:

                     typedef int *ptr,(fun)(),arr[5];// *ptr 是指向int的指针,fun是指向返回值为int的函数指针类型;arr是长度为5int 型数组

       4typedef 和宏替换的区别

              1可以用其他类型的说明符对宏类型名称进行扩展,但typedef却不行:

                     #define peach int

                     Unsigned peach I;//没问题

                     Typedef int banana;

                     Unsigned banana I;//错误

              2在连续几个变量的声明中,用typedef可以保证声明中所有类型的变量均为同一类型,而用#define则无法保证。如:

                     #define int_pty  int *

                     Int_ptr chalk,cheese;

              宏扩展后为 int * chalk,cheese//chalk的定义没错。但cheese则为一个int型变量,而不是期望的int *

       5)关于C语言的名字空间

              在同一个名字空间里,任何名字必须具有惟一性,但在不同的名字空间里可以相同,由于每个结构或者联合具有自己的名字空间,所以同一个名字可以出现在许多不同的结构内,如:

              Struct foo{int foo;}foo;

三、分析C语言的复杂声明

C语言的语法力图使声明和使用想一致,所以情况比较复杂的情况下,容易让人混淆;

这里介绍一种“right-left”规则:

1)规则说明

0. 规则中符号
 *  
读作指向...的指针”  
 []   
读作 “...的数组
”  
 ()  
读作返回...的函数

1.
起始点

 
找到声明中的标识符(Identifier),它就是你分析的起始点,读作:“$(Identifier)...”

2. 右边
 
看你的标识符右边
 a)
如果发现“()”,你将知道这是一个函数声明,这时你可以说“$(Identifier)是返回...的函数
 b)
如果发现“[]”,你将知道这是一个数组声明,这时你可以说“$(Identifier)...的数组
 c)
继续向右,直到遇到右边声明结束或者遇到“)”,继续下面。
3.
左边
 
看你的标识符左边
 a)
如果碰到的不是我们在0.中定义的符号,则直接说出它;否则按照0.中定义的符号含义说出。继续向左,直到遇到左边声明结束或“(”
4.
重复23的步骤,直到声明分析完毕。

2) 例子详解
我们从简单到复杂,循序渐进。
[Example 1] int *p[];
1)
找到标识符:p,读作:“p...”
2)
向右看:发现一“[]”,然后遇到右边声明结尾,读作:“p...的数组
3)
向左看:发现一“*” 读作:“p是指向...的指针的数组
4)
继续向左看:没有发现0.中定义的符号,则分析结束,读作:“p是指向int类型的指针的数组

[Example 2] int *(*func())();
1)
找到标识符:func,读作:“func...”

2)
向右看:发现一“()”,然后遇到“)”,读作:“func是返回...的函数
3)
向左看:发现一“*”,然后遇到“(”,读作:“func是返回指向...的指针的函数
4)
向右看:发现一“()”,然后右边声明结束,读作:“func是返回指向返回...的函数的指针的函数
5)
向左看:发现一“*”,读作:“func是返回指向返回指向...的指针的函数的指针的函数
6)
向左看:没有发现.中定义的符号,则分析结束,读作:“func是返回指向返回指向int类型的指针的函数的指针的函数

3)常见不合法的声明符号组合
包括:
 []() - cannot have an array of functions
 ()() - cannot have a function that returns a function
 ()[] - cannot have a function that returns an array

 

 

阅读(1135) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~