美文网首页
第一章 指针常识

第一章 指针常识

作者: 心无君 | 来源:发表于2016-11-06 15:50 被阅读0次

    和C语言中任何一个部分一样,指针也有其基本的常识。本文不会介绍太多基础的东西,关于指针的常识模块也只是一带而过,如有遗忘,请参考相关书籍。

    1.1 变量

    变量常常出现于表达式中,当变量出现在表达式的左方时,它表示的是某个地址;而当变量出现在表达式的右方时,它表示的是某个地址里存放的值。例如:

    int a = 1; 
    int b =2; a = b;
    

    其中a = b;中的a表示的是a的地址空间,而b表示的是b的地址空间中的内容。a = b则表示将a的地址空间的修改成b的地址空间中的内容。简而言之,对于变量来说,出现在赋值表达式的左边则表示引用其地址,出现在赋值表达式的右边则表示引用其值。整个表达式的意思就是,把某个地址里的内容修改成后面的内容。判断一个赋值表达式是否合法就看赋值的左边是否是个地址,而右边又是否是个值。

    1.2 指针初始化

    定义一个指针只是向编译器申请一个用于存放某个地址的地址空间,而且这个地址空间里的值应该是某个地址,同时,指针本身也是一个变量。由于指针本身也是一个变量,那么它的默认初值、作用域、生存周期等都符合变量的特性。

    指针在使用时一定要先初始化:

    例如,int *p; 则编译器会分配一个4字节的内存用于存放p,但是此时p还未初始化,它的值是不确定的。我们可以用&p取出此指针的地址,用p表示该地址中的内容,但是,用*p引用该指针所指向的变量的值的结果是不可预知的。如果运气好,会崩掉,如果运气不好,就等着程序给你添麻烦吧。

    一般来说指针的使用流程是:

    int *p = NULL;   //定义并附初值0
    int a = 0; p = &a;  //使用前赋值
    cout<<*p<<endl;  //指针引用
    p = NULL;       //不用时清空
    

    1.3 NULL系列

    在C语言中诸如NULL之类的用于帮助程序员理解程序的宏定义\说明有很多,现简要说明一下。

    NUL:ASCII字符集中的’\0’字符的名字,它的字节模式为全0。事实上,根本就不存在预定义的符号NUL,如果想要使用,则必须自己定义。#define NUL 0 或 #define NUL '\0'
    NULL:标识空指针。定义为0 即 #define NULL 0
    false:标识逻辑0。定义为0 即 #define false 0
    true:标识逻辑1。定义为1 即#define false 1
    

    1.4 指针常见错误

    指针最常见的错误就是段错误了。程序在执行时会分成许多段,对段的非法操作统称为段错误。比如,修改只读段的内容,比如访问不属于该程序的段。最为常见的例子就是访问不属于该程序的地址空间。

    一种好的编程风格是在创建指针的时候赋初值NULL,因为一般而言任何操作系统都会把低位地址留给操作系统,把高位地址留给应用程序。当应用程序中引用地址0时会产生访问不属于该程序地址空间的操作,此时就会引发段错误。

    对于某些要求对界的机器而言,当某种类型的数据在内存中的存储地址处在错误的边界上的时候,此时访问这个地址会引发一个总线错误。

    注:本文中各种特例都是在UNIX系统的gcc编译器下调试的,本文所说的各种术语也都适用于UNIX系统,但是对于Windows未必适用。

    问题:段错误的精确定义是什么?段错误和可执行程序的段到底有什么联系?

    1.5 指针常量

    我们可以将一个常量强制转换成指针,虽然这个操作并没有太多的意义,但确实是可以的。例如:

    int * a = (int*) 100; 
    *(int*)100 = 100;
    

    问题:用常量在程序中表示的地址是不是绝对地址?

    相关文章

      网友评论

          本文标题:第一章 指针常识

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