C语言学习之指针第一讲

一、指针

        1.1未初始化和非法指针

         int  *a;

        *a= 12;

        这里声明创建了一个名叫a的指针变量,后面那条赋值语句把12存储字a所指向的内存位置。

        警告:

        这里的a究竟指向哪里?我们声明了这个变量,但是却没有对他进行初始化,所以我们没办法预测12这个值晶存储于什么地方。从这一点看来指针变量和其他变量并无区别。如果变量时静态的,他会被初始化为0;但是如果变量是自动的,他跟被不会被初始化。无论哪种情况,声明的一个整形的指针都不会“创建”用于存储整形值得内存空间。

        所以,如果程序执行这个赋值操作,他会发生什么呢?如果运气好,a的初始值会是个非法的地址,这样赋值语句将会出错,从而终止程序。在UNIX系统上,这个错误被称为“段违例”或“内存错误”。提示程序师徒访问一个并未分配给程序的内存位置。在一台windows的pc上,对未初始化的或者非法指针进行间接的访问操作是一般保护性异常的根源之一。

      对于那些要求整数必须存储于特定便捷的机器而言,如果这种类型的数据内存中的存储地址处在错误的边界上,那么对这个地址进行访问时将产生一个错误,这种错误在unix

上被称为“总线错误”。

        一个更为严重的错误是:这个指针偶尔可能包含了一个合法的地址。接下来的是哪个未知的值被修改,虽然泥饼无意区修改它。想着中类型的错误非常难以捕捉,因为引发错误的代码可能与原先那个操作的代码完全不相干。所以,在哪对指针惊醒间接访问之前,必须非常小心,确保他们已经被初始化。

        1.2指针、间接访问和左值

        a=b;这里符号a的含义是a所代表的地址,习惯上我们称之为左值。而符号b的含义是b所代表的地址的内容,习惯上我们称之为右值,确切的说右值就是除了左值以外的值,他们可能是立即数和变量的某些组合。左值在编译时可知,表示存储结果的地方。通常只有允许修改的左值可以合法用作赋值运算符左边的操作数。所以尽管数组的名字表示“地址”,它是“左值”,但是它不是一个可以修改的左值,所以它也就不能用作赋值运算符的左操作数了,同理,用关键字const修饰的变量也是如此。编译器为每个变量分配一个地址(左值),虽然具体什么时候分配这个地址各个语言的编译器可能有所不同,但是变量在运行时会一直保存于这个地址。

        例子:

         int a;

         int *d + &a;

如果*d =10 -*d;

      d= 10 - *d;

第一条语句包含了连个间接访问操作。右边的间接访问作为右值使用,所有已它的只是d指向的位置所存储的值(a值)。左边的间接范文作为左值使用,所以d指向的位置(a)把赋值符有公测的表达式的计算结果作为他的新值。

        第二条语句是非法的,因为他表示把一个整型数量10-*d存储于一个指针变量中。当我们实际使用的变量类型和应该使用的变量类型不一致时,编译器会发出抱怨,帮助我们判断这种情况。这些警告和错误信息是我们的朋友,编译器通过产生这些信息想我门提供帮助。

1.3指针。间接访问和变量

   *&a = 25;

      答案是把25赋值给变量a,&操作符产生变量a的地址,它是一个指针常量。接着,*操作符访问其操作数所代表的地址。在这个表达式中,操作数是a的地址,所以值25就存储于a中。这条语句同a=25;功能相同。但是他设计更多操作。所以一般没人会故意使用*&a这样的表达式。

1.4指针常量

       *100 = 25;这条语句看起来是把25赋值给a,因为a的位置100所存储的变量。但是这是错的以内字面值100的类型是整型,而间接访问操作只能作用于指针类型表达式。如果你确实想把25存储于位置100,你必须使用强制转换

        *(int*)100 =25;这里强制转换把100从整型转换为指向整型的指针,这样进行间接访问就是合法的。但是需要使用这种技巧的机会是绝无仅有的!以内你无法知道它的地址。

1.4指针的指针

       int a = 12;

        int * b= &a;

        c= &b;

这里c是什么类型?显然他所指向的是整型指针没所以仁和指向b的类型必须是指向整型指针的指针。

     声明指针的指针:

        int  a =12;

        int *b=&a;

        int **c= &b;

这里即为声明一个指针的指针c。

  1.5总结

        1.5.1指针变量的值并非他所指向的内存位置所存储的值。我们必须使用间接访问来获取他所指向位置存储的值。对于一个指向整型的指针施加间接访问操作的结果将是一个整型值。

        1.5.2声明一个指针变量并不会自动分配任何内存。在对指针执行间接访问前,指针必须进行初始化:或者使用它指向的现有的内存,或者给他动态分配内存。对未初始化的指针变量执行间接访问操作是非法的,而且这种错误难以检测。其结果是常常是一个不相关的值被修改。错误很难被调试发现。

        1.5.3NULL指针就是不指向任何东西的指针。他可以赋值给一个指针,用于标识哪个指针并不指向任何值。对NULL指针执行间接访问操作的后果因编译器而异,两个常见的后果分别是返回内存位置零的值以及终止程序。

        1.5.4和任何其他变量一样,指针变量也可以作为左值使用。对指针进行间接访问所产生的值也是个左值,因为这种表达式标识了一个特定的内存位置。除了NULL指针之外,再也没有仁和内建的激发来表示指针常量,因为程序通常无法预测编译器会把变量放在内存中的什么位置。在极少见的情况下,我们偶尔使用指针常量,这时我们可以把一个整型值强制转换为指针类型来创建它。

可参考博客c指针

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值