黑马程序员——C语言—数组、指针

C语言第三篇---数组、指针

 

        在前面学习中,要存储一个数据,可以用一个变量去解决,当存储一组数据的时候,

就要用到整型数组、字符数组、指针数组、结构体数组。数组就是可以存放一组数据,这

样可以减少代码重复,提高性能。

   一、数组


        数组就是数据的整合,那么整型数组的定义的格式是:int 变量名[元素个数];

如:int a[10]; 接着就是数据是怎么存放到整型数组中的,数组的存放有一下几种方式:

   1.在定义时赋值,其余没有赋初始值的默认为0   int a[10]={1,2,3,4}   

   2.在定义时可以对单个进行赋值                int a[10]={[3]=5,[8]=12};

   3.在定义时不赋值,以后赋值必须单个进行赋值  int a[10];   a[1]=1; a[5]=4;

       既然数据可以存放多个数据,它在内存中是这么存放的:
  
代码(字符数组为例):

   int main()
{
    char cs[5]={'a','A','D','e','f'};

    return 0;
}

       内存给数组分配也是从大到小根据占据字节分配,依次的从上到下存放数据,并且cs

的地址就是它的首地址即cs[0],和存储变量的方式很雷同,只不过没有转换成二进制。
 
       函数之间可以传递参数,这个参数可以是变量也可以是数组,要注意的就是传递过去

的是地址,而且默认的把数组当成指针传递过去,指针是8个字节,而数组要根据数据类

型和元素个数来决定,因此传递之前格外注意,需要数组长度时要提前换算出来。

 

二、二维数组

      

       在存储数据用数组,难免有些不足,于是引出了二维数组,在我的理解下,我可以把

二维数组理解成数组的数组,或者把它看成两个一维数组,这样很容易就理解了。二维数

组可以存放的数据更多,实际上就是两个一维数组(呵呵,我怎么这么犟呢),举个例子:

  int a[3][2]={{1,2},{3,4},{8,12}};

       这就是个简单的二维数组,那么数组的输出方式可以用for循环来实现:


  三、字符串

      

        字符串就是一个一维数组,它就是由很多个字符组成,需要注意的就是字符串的末尾

是以'\0'为结束标志。例如:

     char p[10]="minglei";  或  char p[]={'m','i','n','g','l','e','i','\0'};

       如果是以上面第二种方式赋值一定在最后面加上'\0',否则后果严重,字符串只认'\0'为

结束,找不到则去上一个字符串中去找,直到找到为止。因此错误的写法是:

char name[] ={'o','k'};  

 

四、sizeof和strlen


   
       sizeof和strlen的不同:'\0'也占据一个字节空间,因此用sizeof求所占字节数需要算

上'\0',而strlen只是单纯求字符串的长度,因此不算上'\0'。并且在用strlen这个函数时,需要

加头文件string.h

       字符数组只能存储一个字符串,这往往时不能满足我们需求的,因此引出字符串数组

 ,也就是字符二维数组,可以存放多个字符串。

 

五、结构体


       结构体类型,是我们人为的去定义一种类型供我们使用,这种类型可以存放多种数据

 类型,比如整型,浮点型,字符,数组,指针等,它的作用非常广,这样定义有点面向对

 象的意思,把一个对面的属性封装了起来。
  
      它定义的格式是:struct 类型名称{成员1,成员2....};定义结构体变量有以下两种:

1.   struct Student
{
   char name[10];
    short  age;
};
  
struct Student stu={"minglei",23};

 

2. struct Student
{
     char name[10];
     short  age;
}stu,stu2;


      一种是先定义类型,再定义变量,另一种在定义类型的同时也定义了变量。

     它的数据这么复杂,其实在内存中存储也是一样的,只不过它分配空间是从小往大分

 配,正好反了过来。(定义一个数据类型并不分配内存)结构体所占的内存并不是所有成

 员的总和,而是成员中最大类型的字节数的倍数。例如:

    struct Student
{
   char name[10];
   int age;
};
 

       这段代码中,结构体所占的内存是8个字节,并不是14。当然定义一个结构体相当于一

 个对象,那么有多个对象怎么办呢,就是结构体数组。就好比定义的Student类型,有好

 多学生似地,很通俗的理解了,那么在访问成员属性时用变量名.属性名,这一点就更像

 面向对象编程了。

       for可以进行嵌套,结构体也不例外,例如:一个学生有多门学科成绩,这些成绩可以

封装在一个结构体中,多个学生都有这些成绩。就是学生结构体嵌套成绩结构体。

 

 六、枚举

 

       和结构体类似的一种类型是枚举类型,枚举可以限定编程人员对一些变量赋固定的值

,这些值只能是枚举类型中定义的,没有定义的是不能随便赋其它的值。定义枚举类型的

格式是:enum 类型名{固定值1,固定值2....}

 


七、指针

 

      C语言的核心就是指针,指针可以操作内存,间接性的修改内存里的数据,并且它的运

 用很广泛,有数组指针,字符指针,字符串指针,指针的指针,函数的指针,结构体的指针

等,基本上是无所不指。指针的作用那么大,其实它就是个数据类型,它就是用来存放地址

的,通过它存放的地址可以访问到这个地址的存储空间。

     1. 数组指针,顾名思义就是定义一个指针,指针里存放的值就是数组的地址。例如:
 
  int a[3]={1,2,3};

  int *p=a;

   (int *)这是一体的,而变量p就是指针,这里是把a的地址给了指针p,并不是数值。而且

 在定义指针时,数据类型要和所指向的数据类型一致。即数组a的int类型,因此指针p的类型

也必须是int类型,否则后果不堪设想。既然指针可以访问数据,那么指针到底是怎么把数组

的数据访问到的,代码如下:


#include <stdio.h>
int main()
{
   int a[3]={1,2,3};

   int *p=a;

   int i; int size=sizeof(a)/sizeof(int);
 
   for(i=0;i<size;i++)
{
  printf("%d",*p);
 
  p+=1;
}

}

       代码中  *p就是访问p当前地址的存储空间里的值,而p+1 并不是数值+1,而是p的地址是

数组中下一个地址,所谓的+1,取决与数据类型,int类型4个字节,因此p+1是后4个字节的地

址,也就是数组a中的下一个地址,从而达到了遍历数组的功能。 
 
      2.字符指针就是单个字符的指针,比较关注的还是字符串指针,也就是字符数组指针,但是在

定义时完全可以用指针去代替,例如:
 
  char *name="minglei";    //字符串常量

  一般的定义是:

  char name[10];           //字符串变量

  char *n=name; 

       直接用指针的话,切记一点就是不可以再修改,而后面定义的就不同了,以后任何一个字符

都可以单独的拿出来访问修改。字符串指针用的很多,很多情况下都是和字符串去打交道的。

       指针的指针这个就比较难理解了,其实想明白了很简单,无非就是将一个指针存放另一个指

针的地址,从而找到指针里存放的地址的存储空间,打个比方说:小明有本书,小明认识小白,

小白认识小李,那么小李就可以通过小白找到小明得到这本书。在定义指针的指针时需要注意一

点,指针要指向的变量,要和该变量数据类型一致,那么指针的数据类型是和*一体的,例如:定

义一个指针pp指向指针p;

   int a=5;         变量a的数据类型为int
   
   int *p=a;        指针p的数据类型为int *
 
   int **pp=p;      指针pp的数据类型为int **

       只要记住(数据类型 *)是一体的就很容易理解了。

       3.指向函数的指针,这个就没有听说过,我们调用函数时都是用函数名();去调用,那么用指针

也可以实现调用,代码如下:

#include <stdio.h>

   int test(int a,int b)
{

   return a+b;
}

int main()
{
   int (*p)()=test;

   printf("%d",p(5,7));
 
   return 0;

}

       就这样,我们可以间接性的用指针去调用了函数,指针真的是太有趣了,简直无所不能。

       4.结构体指针和枚举指针,这两个类似,唯一一个可以让指针升华的地方就是,结构体变量访

问成员属性是通过 . 的方式,而用指针则可以用 -> 很华丽的指向方式去访问,例如:

 #include <stdio.h>

int main()
{
   struct Student
{
   char name[10];
   short  age;
};

   struct Student stu={"minglei",23};

   struct Student *p=&stu;

   printf("name=%s,age=",p->name,p->age);


}


      总结:指针的用途很广,可以说还是无所不能,只有你想不到的,没有指针做不到的。真的是学好指针才能真正明白C语言的真

谛,“上天入地,指哪到哪”,并且用指针去操作内存,可以大大的节省性能,大爱指针。


      明天就要学OC了,内心还有点小激动呢,期待OC的到来,期待未来光明的黑马路。 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值