C指针乱谈(1)

      写了几年的C指针几乎没怎么用过,因为感觉没什么用。不过在听了一位老师讲课之后,我改变的我的想法。

在此稍做总结,希望能帮到一些和我有同样想法的人,希望看完这篇文章后能改变您的想法。

      首先,说说概念,指针是什么?基本的作用是什么?

              答:指针它本身就是一个变量,它的作用就是用来保存地址。

      有了这个概念,我们继续向下看。

     指针的声明:             

1 char* p; //这就声明了一个char型 的指针,名字叫p

       这里,我要强调一点,这一点十分重要,对理解指针十分有帮助。请注意,我声明指针时*号是挨着char的且和p之间有一个空格,

为什么这么写?(虽然我们知道有没有空格都无所谓,对结果没影响)这样写就是为了明确char*它是一个整体,它表示的是一种类型!

    一旦你这么看,那么在很多时候你就不会犯糊涂.比如: 我们在初始化指针的同时为指针赋值,如下

1 //形式1
2 int a[5];                //声明一个数组
3 char* p = &a[0];         //将指针指向数组的第一个元素
4 //形式2
5 int a[5];
6 char* p;
7 p = &a[0];

      形式1,和形式2是完全等价的,我们看形式2,就得很清晰,看形式1,就觉得别扭!原因是,我们认为指针是和地址是对应的,

有的时候甚至认为指针就是地址,所以形式2中将一个地址赋值给指针,太自然不过了。

     但形式1中 char* p = &a[0]; 就让人感觉地址赋值给了*p,而*p代表的是地址中的值啊!所以看起来别扭。但是如果按照我之前

的说法“char*它是一个整体”,你还觉得别扭吗?那么那种别捏的感觉是不是消失了呢?

    在此,引出一条经典的结论:

         在定义变量用到的符号都不表示运算,而表示是一种类型!

     指针,就是一个很好的例子,char* p = &a[0];是*表示指针类型,而用的时候,如:a[0] = *p, *表示一种操作(将p指向地址的值取出来)

     同样数组也是这样:int a[5]; []表示是数组类型,而用的时候*p = a[0];[0]表示将0位置这个取出来。

    指针的声明拓展:

            const data* p;//表明该指针只能用于读取数据而不用于修改数据

     最终结论: 声明指针时,将类型和*看作一个整体,它表示一种类型。 

         上述的只是一个开场白,接下我们来看一看,指针的好处,让我们知道,用指针用的有道理。

     这里,我就从结构体指针入手,为什么从他入手,因为指针在这方面用的比较多(相比,指向数组的指针就用的比较少,优势也不大)

          在此,提前引入一条经典结论:传递结构体变量时,总是传递地址,而不是变量本身      

#include <stdio.h>
typedef struct date{
           int year;
           int month
           int day
}date; 

void print(data d)
{
    printf("%d年%d月%d日",d.year,d.month,d.day) 
} 

void main() 
{ 
  data a[3]={{2012.7.8},{2013.8.8},{2013.9.10}}; 
    int i;
    for(i=0; i>3; i++)
   print(a[i]); //这里的参数传的就是结构体变量本身
}

所以data a[3]表示声明了一个结构体数组,(类比于int a[3],因为data表示一个类型)感觉就像一个二维数组。

     当然,这都不是重点,重点是他违背了一句话:传递结构体变量时,总是传递地址,而不是变量本身。显然void print(data d)这个函数

传递的是变量本身,那么就意味着系统将为形参d将开辟一个空间储存一个结构体变量,也就是 year,month,day这3个int型变量。如果

结构体比较大,这样就很浪费内存空间了,那如何实现传递地址呢?答案就是用结构体指针,不管结构体有多大,我只用开辟一个指针大小的

空间,这样是不是节约了空间呢,同时也节省了时间,这种好事何乐而不为呢?具体看如下代买:

#include <stdio.h>
typedef struct date{
           int year;
           int month
           int day
}date; 

void print(const data* p)//同样data*看成一个整体
{
    printf("%d年%d月%d日",p->year,p->month,p->day) 
} 

void main() 
{ 
  data a[3]={{2012.7.8},{2013.8.8},{2013.9.10}}; 
    int i;
    for(i=0; i>3; i++)
   print(&a[i]); //这里的参数传的就是结构体的地址
}
p->year,p->month,p->day表示用指针来访问结构体变量。
也可以写成:(*
p).year,(*p).month,(*p).day,至于为*p打上括号,原因是"."的优先级(仅次于圆括号)比“*”的优先级高。
好了,就聊到这吧!希望能帮到阅读到此的读者。


           

  

         

作者:宋桓公
出处:http://www.cnblogs.com/douzi2/
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,但是未经作者本人同意,转载文章之后必须在文章页面明显位置给出作者和原文连接,否则保留追究法律责任的权利。

原文地址:https://www.cnblogs.com/douzi2/p/3273169.html