`
michael-java
  • 浏览: 18859 次
  • 性别: Icon_minigender_1
  • 来自: 合肥
最近访客 更多访客>>
社区版块
存档分类
最新评论

第七章 C语言声明详解

阅读更多

 

人们常说,C语言的声明太复杂了,的确,这也是C语言饱受批评的地方之一。不过,笔者认为,真正要受到批评的不是语言本身,而是那些传播者。传播者们通常都有一个共识:讲述要由浅入深。作为原则,笔者并非要反对它,毕竟笔者对C语言的学习,也经历了相同的过程。但是,由浅入深并不意味着一切从简,以偏盖全。计算机语言不同于数学理论(虽然它的确根植于数学,与数学密不可分),数学理论是一种循序渐进的过程,后面的理论以前面的理论为基础。但C语言归根说底,就是一堆语言规则而已,应该让学习者一开始就全面且详细地了解它,而不是象现在某些教材所做的那样,只说一部分,不说另一部分,以为这就是由浅入深了,实际上这是以偏盖全。

        语言如此,声明作为C语言的一部分更是如此。我们最常见到的对声明的描述是这样的:

存储类别  类型限定词  类型  标识符

这种说明会给人们一种暗示:C语言的声明是静止的、死板的,什么声明都能够以这个为基础,往上一套就OK了。事实真的如此吗?说句心里话,笔者也祈祷事实真的如此,这样世界就简单多了、清静多了。但别忘了,这个世界总是让人事与愿违的。实际上,C的声明的组织形式是以嵌套为基础的,是用嵌套声明组织起来的,并非象上面所述那么死板,存储类说明符一定得放在限定词前面吗?类型说明符一定要紧贴标识符吗?不!C标准从来没有这样说过!下面来看一看C89对声明的形式是如何规定的:

声明:

声明说明符   初始化声明符表opt  [opt的意思是option,可选]

其中声明说明符由以下三项构成:

声明说明符:

存储类说明符  声明说明符opt
类型说明符    声明说明符opt
类型限定符    声明说明符opt

在这里,一个声明说明符可以包含另一个声明说明符,这就是声明的嵌套,这种嵌套贯穿于整个声明之中,今天我们看来一个非常简单的声明,其实就是由多个声明嵌套组成的,例如:

static const int i=10, j=20, k=30;

变量i前面就是声明说明符部分,有三个声明说明符:static const int,static是一个存储类说明符,它属于这种形式:

static 声明说明符

static后面的声明说明符就是const int,const是一个类型限定符,这也是个嵌套,它是由

const 声明说明符

组成,最后的int是一个类型说明符,到这里已经没有嵌套了,int就是最底的一层。对于存储类说明符、类型说明符和类型限定符的排列顺序,C标准并没有规定其顺序,谁嵌套谁都可以。换言之,上面的声明可以写成:

int static const i=10, j=20, k=30;或者const int static i=10, j=20, k=30;

这无所谓,跟原声明是一样的。再举一个有趣的例子:

const int *p;与int const *p;

有些人会对后面一种形式感到困惑,因为他一直以来学习的都是那种死板的形式,因此他无法理解为什么那个const可以放在int的后面。实际上对于标准来说,这是再正常不过的行为了。

上面举的例子是变量的声明,函数的声明也同样道理,例如:

static const int func(void);
......

int main(void)
{
        int static const (*p)(void);
        p=func;
        .........
        return 0;
}

const int static func(void)
{
        .......
        return 0;
}

func的函数原型声明、函数定义跟main内的函数指针p的声明是一样的。但是,笔者并非鼓励大家把声明说明符写得乱七八糟,作为一个良好的风格,应该按照已经习惯约定的方式排列说明符,但懂得其中的原理非常重要。

声明static const int i=10, j=20, k=30;的int后面的部分就是初始化声明符表,这比较容易理解,这个符表实际上也是嵌套的:

初始化声明符表:

初始化声明符
初始化声明符表, 初始化声明符


初始化声明符:

声明符
声明符=初值


        声明符是初始化声明符的主体,现在来讨论一下声明符是如何规定的:

声明符:

指针opt  直接声明符

这里写的指针opt指的是那个指针声明符*,要注意的是,*属于声明符,而不是声明说明符的一部分。

指针opt又包含:

指针:

* 类型限定符表opt
* 类型限定符表opt 指针

在这里有一个常见的问题,就是const int *p;与int * const p的区别,第一个声明的const属于声明说明符,它跟int一起,是用来说明*p这个声明符的,因此const修饰的是p所指向的那个对象,这个对象是const的。而第二个声明的const是声明符的一部分,它修饰的对象是p本身,因此p是const的。

        上面规定的第二条值得注意,这条规定产生了一种指针与const的复杂形式,例如:

const int * const *** const ** const p;(是不是有种想冲向厕所的冲动?)这是一种复杂的声明嵌套,如何解读这种声明?其实只要掌握了它的规律,无论它有多少个const、多少个*都不难解读的,这个内容我将在第九章进行解释。

        剩下的就是直接声明符和类型限定词表的内容:

直接声明符:

标识符
(声明符)
直接声明符[常量表达式opt]
直接声明符(形式参数类型表)
直接声明符(标识符表opt)


类型限定符表:

类型限定符
类型限定符表 类型限定符


        这一章的最后一个内容,是讨论一下typedef,typedef用来声明一个别名,typedef后面的语法,是一个声明。本来笔者以为这里不会产生什么误解的,但结果却出乎意料,产生误解的人不在少数。罪魁祸首又是那些害人的教材。在这些教材中介绍typedef的时候通常会写出如下形式:

typedef int PARA;

这种形式跟#define int PARA几乎一样,如前面几章所述,这些教材的宗旨是由浅入深,但实际做出来的行为却是以偏盖全。的确,这种形式在所有形式中是最简单的,但却没有对typedef进一步解释,使得不少人用#define的思维来看待typedef,把int与PARA分开来看,int是一部分,PARA是另一部分,但实际上根本就不是这么一回事。int与PARA是一个整体!就象int i:声明一样是一个整体声明,只不过int i定义了一个变量,而typedef定义了一个别名。这些人由于持有这种错误的观念,就会无法理解如下一些声明:

typedef int a[10];
typedef void (*p)(void);

他们会以为a[10]是int的别名,(*p)(void)是void的别名,但这样的别名看起来又似乎不是合法的名字,于是陷入困惑之中。实际上,上面的语句把a声明为具有10个int元素的数组的类型别名,p是一种函数指针的类型别名。

虽然在功能上,typedef可以看作一个跟int PARA分离的动作,但语法上typedef属于存储类声明说明符,因此严格来说,typedef int PARA整个是一个完整的声明。

分享到:
评论

相关推荐

    c语言详解PDF

    《C语言详解》这本书是学习C语言的重要参考资料,它涵盖了C语言的基础到高级概念,适合初学者和有一定经验的程序员阅读。尽管书中可能存在没有跳转书签的不便,但这并不影响其作为一本深入理解C语言的教程的价值。 ...

    C语言详解(第5版) 相关课本例题源代码

    《C语言详解(第5版)》是一本深入解析C语言的经典教材,由Jeri R. Hanly和Elliot B. Koffman合著,属于图灵计算机科学丛书中的一部。这本书以其详尽的解释、丰富的实例和严谨的讲解闻名,是学习C语言的重要参考资料...

    c语言指针详解.pdf

    ### C语言指针详解 #### 一、引言 C语言作为一门强大的系统级编程语言,在计算机科学领域占据着极其重要的地位。其中,“指针”是C语言中最核心且复杂的一部分,也是许多初学者难以攻克的技术壁垒。指针在C语言中...

    实用C语言详解

    《实用C语言详解》这本书是针对C语言编程者的一份详尽指南,旨在帮助读者深入理解和熟练掌握C语言。C语言是一种广泛应用的编程语言,它以其高效、灵活和可移植性而闻名,广泛用于系统编程、嵌入式开发、软件开发等多...

    c语言指针详解.docx

    ### C语言指针详解 #### 一、引言 C语言是一种广泛使用的程序设计语言,以其高效、灵活而著称。在C语言中,指针是处理内存的强大工具,但同时也是最容易导致错误的地方之一。本篇文章将深入探讨C语言中的指针概念...

    C语言指针详解.docx

    ### C语言指针详解 #### 一、引言 C语言是一种广泛使用的程序设计语言,以其高效性和灵活性著称。其中,指针是C语言的一个重要特性,它为程序员提供了直接操控内存的能力,极大地增强了程序的功能性和性能。本文将...

    C语言基础知识详解.docx

    c语言基础目录第一章 初识C语言1.C语言基础知识2.C语言的构成3.第一个C语言程序4.数据类型5.C的标识符5.1标识符的命名规则5.2标识符的分类6.变量6.1定义变量的方法6.2变量的分类 6.3变量的使用6.4变量的作用域和生命...

    c语言课程详解、教案、大纲

    - 第七、八节:安排小组讨论或编程作业,提高协作和独立解决问题的能力。 - 课外活动:鼓励学生参与编程竞赛或项目,提升实战能力。 - 晚自习:学生自主学习,完成作业,教师提供答疑指导。 三、教案设计: 教案应...

    彻底搞定C语言指针详解-完整版-时候初学者-必备

    ### 彻底搞定C语言指针详解 #### 一、理解C语言中的指针概念 在C语言中,指针是一种非常重要的数据类型,它存储的是内存地址而非具体的数据值。掌握指针对于深入理解和高效编程至关重要。 ##### 1.1 内存地址与...

    C语言函数库详解

    C语言函数库详解 C语言,作为一种强大的编程语言,其函数库是其核心部分,它提供了丰富的功能,帮助程序员高效地实现各种计算和任务。C语言的函数库分为标准库和非标准库,其中最常用的是标准库,也就是C语言标准...

    第一章 c语言基础知识.doc

    【知识点详解】 1. **C语言特点**:C语言是一种结构化编程语言,以其简洁紧凑的语法、强大的功能和良好的可移植性著称。它允许程序员直接对硬件进行操作,因此在系统编程和嵌入式领域广泛应用。C语言的移植性好,...

    C语言 第7章 数组

    ### C语言第7章 数组知识点详解 #### 一、数组概述 数组是C语言中非常重要的一种数据类型,它能够帮助我们有效地管理一系列相同类型的数据。数组中的元素必须具有相同的类型,可以是一维的,也可以是多维的。 **...

    江苏二级C语言考试上机指导详解

    ### 第二章:C语言上机实验内容 这部分内容涵盖了C语言的基础到进阶知识点,通过一系列实验来帮助考生实践和巩固所学: #### 实验1:C程序的运行环境和运行方法 考生需要了解C程序的生命周期,包括编译、链接和...

    C语言指针详解

    ### C语言指针详解 在计算机编程领域,尤其是在C语言中,指针是理解与高效操作内存的关键概念之一。本文将全面介绍C语言中的指针概念,并深入探讨其使用方法及注意事项。 #### 一、基本概念 在C语言中,指针是一...

    c语言教学课件(能够更通俗易懂的学习C语言)

    7. **第7章_指针** C语言的指针是其强大之处,它允许直接操作内存。这一章将详细介绍指针的概念、声明、初始化,以及指针运算和指针与数组的关系。 8. **第8章_结构体与共用体** 结构体和共用体是C语言中的复杂...

    详解C语言Struct(结构体)系列之一

    在C语言中,结构体的声明、定义和初始化是基本操作。声明结构体时,我们通常使用struct关键字后跟结构体的名称和其中包含的成员。定义结构体时,会指定具体成员的类型和名称。初始化结构体,则是为结构体中的每个...

    C语言第7章PPT课件.pptx

    【C语言函数详解】 在C语言中,函数是程序的基本模块,它们负责执行特定的任务。函数分为两类:无参函数和有参函数。无参函数的一般形式是声明函数类型后跟着函数名,然后括号内是`void`,表明该函数不需要任何参数...

Global site tag (gtag.js) - Google Analytics