美文网首页C语言C语言从入门到入坟
C语言学习:C语言关键字(四)

C语言学习:C语言关键字(四)

作者: 源世界Z | 来源:发表于2018-05-29 22:04 被阅读0次

    正文共:3689 字 2 图。预计阅读时间: 10 分钟。

    主要内容:C语言关键字详解,void和sizeof.

    什么是关键字

    关键字是系统定义的,具有特定含义、专门用于特定用途的C语言标识符,也称为保留字。关键字一般为小写字母,在使用时必须遵守一定的语法规则,如果随意使用关键字,可能会出现意想不到的错误,有时程序虽然编译通过,但结果运行不正确,并且很难检查出来。标准C语言共有32个关键字。

    昨天我们讲了两个C语言关键字typedf和struct。不明白的可以查看我的前一篇文章。今天的也讲两个大家比较熟悉的关键字。void和sizeof。先说void,void是是属于数据类型。它的含义是无值型。而sizeof是属于运算符。它的含义是求子节数,经常用到的。

    void详解,找好板凳:

    一、void a?

    void 的字面意思是“空类型”,void *则为“空类型指针”,void *可以指向任何类型的数据。
    void 几乎只有“注释”和限制程序的作用,因为从来没有人会定义一个void 变量,看看下面的例子:
       void a;
    Visual C++6.0 上,这行语句编译时会出错,提示“illegal use of type 'void'”。不过,即使void a 的编译不会出错,它也没有任何实际意义。
    void 真正发挥的作用在于:

    对函数返回的限定;

    对函数参数的限定。

    众所周知,如果指针p1 和p2 的类型相同,那么我们可以直接在p1 和p2 间互相赋值;如果p1 和p2 指向不同的数据类型,则必须使用强制类型转换运算符把赋值运算符右边的指针类型转换为左边指针的类型。例如:
       float *p1;
       int *p2;
       p1 = p2;
    其中p1 = p2 语句会编译出错,提示“'=' : cannot convert from 'int *' to 'float *'”,必须改为:
       p1 = (float *)p2;
    而void *则不同,任何类型的指针都可以直接赋值给它,无需进行强制类型转换:
       void *p1;
       int *p2;
       p1 = p2;
    但这并不意味着,void *也可以无需强制类型转换地赋给其它类型的指针。因为“空类型”可以包容“有类型”,而“有类型”则不能包容“空类型”。

    二、void 修饰函数返回值和参数

    1、如果函数没有返回值,那么应声明为void 类型。在C 语言中,凡不加返回值类型限定的函数,就会被编译器作为返回整型值处理。但是许多程序员却误以为其为void 类型。例如:
    add ( int a, int b )
    {
       return a + b;
    }

    intmain(int argc, char* argv[]) //甚至很多人以为main 函数无返回值  //或是为void 型的
    {
       printf ( "2 + 3 = %d", add ( 2, 3) );
    }
    程序运行的结果为输出: 2 + 3 = 5。这说明不加返回值说明的函数的确为int 函数。
    因此,为了避免混乱,我们在编写C 程序时,对于任何函数都必须一个不漏地指定其类型。如果函数没有返回值,一定要声明为void 类型。这既是程序良好可读性的需要,也是编程规范性的要求。另外,加上void 类型声明后,也可以发挥代码的“自注释”作用。所谓的代码的“自注释”即代码能自己注释自己。
    2、如果函数无参数,那么应声明其参数为void。无论在C 还是C++中,若函数不接受任何参数,一定要指明参数为void。

    三、void 指针

    1、千万小心又小心使用void 指针类型。按照ANSI(American National Standards Institute)标准,不能对void 指针进行算法操作,即下列操作都是不合法的:
       void * pvoid;
       pvoid++; //ANSI:错误
       pvoid += 1; //ANSI:错误
    ANSI 标准之所以这样认定,是因为它坚持:进行算法操作的指针必须是确定知道其指向数据类型大小的。也就是说必须知道内存目的地址的确切值。例如:
       int *pint;
       pint++; //ANSI:正确
    但是大名鼎鼎的GNU(GNU's Not Unix 的递归缩写)则不这么认定,它指定void *的算法操作与char *一致。因此下列语句在GNU 编译器中皆正确:
       pvoid++; //GNU:正确
       pvoid += 1; //GNU:正确
    在实际的程序设计中,为符合ANSI 标准,并提高程序的可移植性,我们可以这样编写实现同样功能的代码:
       void * pvoid;
       (char *)pvoid++; //ANSI:正确;GNU:正确
       (char *)pvoid += 1; //ANSI:错误;GNU:正确
    GNU 和ANSI 还有一些区别,总体而言,GNU 较ANSI 更“开放”,提供了对更多语法的支持。但是我们在真实设计时,还是应该尽可能地符合ANSI 标准。
    2、如果函数的参数可以是任意类型指针,那么应声明其参数为void *。
    典型的如内存操作函数memcpy 和memset 的函数原型分别为:

       void * memcpy(void *dest, const void *src, size_t len);
       void * memset ( void * buffer, int c, size_t num );

    这样,任何类型的指针都可以传入memcpy 和memset 中,这也真实地体现了内存操作函数的意义,因为它操作的对象仅仅是一片内存,而不论这片内存是什么类型。如果memcpy和memset 的参数类型不是void *,而是char *,那才叫真的奇怪了!这样的memcpy 和memset明显不是一个“纯粹的,脱离低级趣味的”函数!
    下面的代码执行正确:
    例子1:memset 接受任意类型指针
       int IntArray_a[100];
       memset (IntArray_a, 0, 100*sizeof(int) ); //将IntArray_a 清0
    例子2:memcpy 接受任意类型指针
       int destIntArray_a[100], srcintarray_a[100];   //将srcintarray_a 拷贝给destIntArray_a
       memcpy (destIntArray_a, srcintarray_a, 100*sizeof(int) );
    有趣的是,memcpy 和memset 函数返回的也是void *类型,标准库函数的编写者都不是一般人。

    四、void 不能代表一个真实的变量

    void 不能代表一个真实的变量。因为定义变量时必须分配内存空间,定义void 类型变量,编译器到底分配多大的内存呢。
    void 的出现只是为了一种抽象的需要,如果你正确地理解了面向对象中“抽象基类”的概念,也很容易理解void 数据类型。正如不能给抽象基类定义一个实例,我们也不能定义一个void(让我们类比的称void 为“抽象数据类型”)变量。

    sizeof-了解一下


    一、常年被人误认为函数。

    sizeof 是关键字不是函数,其实就算不知道它是否为32 个关键字之一时,我们也可以借助编译器确定它的身份。看下面的例子:
       int i=0;
    A),sizeof(int); B),sizeof(i); C),sizeof int; D),sizeof i;
    毫无疑问,32 位系统下A),B)的值为4。那C)的呢?D)的呢?在32 位系统下,通过Visual C++6.0 或任意一编译器调试,我们发现D)的结果也为4。
    咦?sizeof 后面的括号呢?没有括号居然也行,那想想,函数名后面没有括号行吗?由此轻易得出sizeof 绝非函数。
    好,再看C)。编译器怎么怎么提示出错呢?不是说sizeof 是个关键字,其后面的括号可以没有么?那你想想sizeof int 表示什么啊?int 前面加一个关键字?类型扩展?明显不正确,我们可以在int 前加unsigned,const 等关键字但不能加sizeof。好,记住:sizeof 在计算变量所占空间大小时,括号可以省略,而计算类型(模子)大小时不能省略。一般情况下,咱也别偷这个懒,乖乖的写上括号,继续装作一个“函数”,做一个“披着函数皮的关键字”。
    做我的关键字,让人家认为是函数去吧。

    二、sizeof(int)*p 表示什么意思?

    表示计算int型所占字节数,然后再乘以p。

    如果是这种形式的话:sizeof(int *p),表示计算指向整型的指针变量p所占的字节数。

    总结:


    C语言关键字32个,讲了比较典型的几个,就到这里了,更多的是自己在实践中的运用,不懂得再问我或看书吧。以后打算以讲一种小例子深入或者写点有意思、有深度的东西了,不想做一些知识点的搬运,没意思,你们有问题的也可以直接问,好吧,就这样!

    文章由源世界编辑,不得私自修改侵权发表,转载请联系作者!

    欢迎订阅点赞,谢谢!

    关注我们:源世界Z

    关注公众号每天收听我们的消息,源世界为您奉上精品文章。

    相关文章

      网友评论

        本文标题:C语言学习:C语言关键字(四)

        本文链接:https://www.haomeiwen.com/subject/kmlzjftx.html