20.指针本质及相关符号

来源:互联网 发布:粮油统计网络直报系统 编辑:程序博客网 时间:2024/05/16 01:16

20.1.指针到底是什么
(1)指针的实质就是个变量,它和普通变量没有任何本质区别。指针完整的名字应该叫指针变量,简称为指针。
(2)int a;和int *p;则编译器在内存空间分别分配2个4字节的内存空间,并将分配的内存空间分别与符号a和符号p绑定起来。针变量虽然实质上也是普通变量,但是它的用途和普通变量不同。指针变量存储的应该是别的变量的地址,而不是用来随意存放任意的数值。
(3)指针的出现是为了实现间接访问,在汇编语言中存在间接访问即CPU寻址方式中的间接寻址。间接访问是CPU设计时决定的,则汇编语言必须能够实现间接寻址,汇编之上的C语言也必须实现间接寻址。高级语言如Java、C#等没有指针,但是高级语言对指针本身进行了封装。


20.2.指针使用步骤
(1)定义指针变量、绑定指针变量、解引用。
(2)当我们定义一个指针变量p时,因为p是局部变量,所以也遵循C语言局部变量的一般规律(定义局部变量并且未初始化,则值是随机的),所以此时p变量中存储的是一个随机的数字。此时如果我们解引用p,则相当于我们访问了这个随机数字为地址的内存空间。那这个空间到底能不能访问不知道(也许行也许不行),所以如果直接定义指针变量未绑定有效地址就去解引用几乎必死无疑。
(3)指针绑定的意义是为了让指针指向一个可以访问、应该访问的地方,指针的解引用是为了间接访问目标变量。


20.3.指针带来的相关符号的理解
(1)我们写的代码是给编译器看的,代码要想达到预定的效果,就必须按照编译的思维进行编写代码,而编译器理解代码就是理解符号,则我们需要正确理解C语言中的符号。
(2)星号:C语言中的星号可表示乘号,也可表示指针符号,这两个用法毫无关联,只是恰好用到了同一个符号而已。在指针定义时,星号结合前面的类型用于表明要定义的指针类型;在指针解引用时,*P表示P指向的变量本身。
(3)取地址符&:取地址符直接加在变量的前面,然后取地址符和变量加起来构成一个新的符号,该符号表示该变量的地址值。


20.4.指针定义和初始化及赋值
(1)指针定义时可以初始化,指针的初始化其实就是给指针变量初值,与普通变量的初始化没有任何区别。
(2)指针变量定义同时初始化的格式是:int a = 32; int *p = &a;。
(3)不初始化时指针变量先定义再赋值:int a = 32; int *p =NULL; p = &a;。


20.5.左值和右值
(1)放在赋值运算符左边的为左值,在赋值运算符右边的为右值,则赋值操作其实就是:左值 = 右值。
(2)当某个变量做左值时,编译器会将其解析成该变量所对应的内存空间;当某个变量做右值的时,编译器会将其解析成该变量所对应的内存空间中存放的具体数值。
(3)左值与右值的区别,就好象现实生活中”家”这个字的含义。譬如”我回家了”,这里面的家指的是你家的房子(类似于左值);但是说”家比事业重要”,这时候的家指的是家人(家人就是住在家所对应的那个房子里面的人,类似于右值)。


20.pointer_symbol/* * 公司:XXXX * 作者:Rston * 博客:http://blog.csdn.net/rston * GitHub:https://github.com/rston * 项目:指针到底是什么 * 功能:演示指针的相关符号。 */#include <stdio.h>int main(int argc, char **argv){    int *p1 = NULL, a1 = 0;         // 定义指针变量P1并赋值为NULL,定义整型变量a1并赋值为0    int *P2 = NULL, *a2 = NULL;     // 定义指针变量P2和a2并赋值为NULL    return 0;}

20.what_is_pointer/* * 公司:XXXX * 作者:Rston * 博客:http://blog.csdn.net/rston * GitHub:https://github.com/rston * 项目:指针到底是什么 * 功能:演示指针的本质和解引用的注意事项。 */#include <stdio.h>int main(int argc, char **argv){    int a = 0;                  // 定义1int类型的变量a,并初始化为0int *p = NULL;              // 定义1个指针变量p,指针变量p所指向的变量为int型,并初始化为NULL    p = 4;                      // 将整数4赋值给指针变量,类型不匹配,编译器报警告    p = (int *)4;               // 将整数4强制类型转换为(int *)类型的4,类型匹配,编译器通过    // 定义指针变量    int *pointer = NULL, b = 1;             // 定义1个指针变量P,指针变量P指向的变量为int型;定义int型变量b    // 绑定指针变量    pointer = &b;                           // 给指针变量赋值,将int型变量b的地址值赋给指针变量pointer    // 解引用    *pointer = 10;                          // 通过指针变量pointer进行间接访问整型变量b    printf("*pointer = %d.\n", *pointer);   // *pointer = 10.    printf("pointer = %p.\n", pointer);     // pointer = 0xbf854684.该值是指针变量本身数值即整型变量b的地址值    printf("&b = %p. &pointer = %p.\n", &b, &pointer);  // &b = 0xbf854684. &pointer = 0xbf854680.    // 演示指针未经初始化即进行解引用的危害    int *p2test;                            // 定义了指针变量p2test但并未赋初值,则该指针指向未知的内存空间    //*p = 888;                             // Segmentation fault (core dumped),段错误,访问了不该访问的地址空间。    int *p2null = NULL;    //*p = 999;                             // Segmentation fault (core dumped),段错误,访问了不该访问的地址空间。    printf("p2null = %p.\n", p2null);       // p2null = (nil). nil表示无值,任何变量在没有被赋值之前的值都为nil    return 0;}

0 0
原创粉丝点击