C程序设计导引(5)

第6章 数组

6.1 定义和使用

虽然数组放到很靠后的位置,但实际上它与intdouble等在难度上没有本质区别。我们可以把一个数组理解为一组格子,格子的名称就是数组的名字。

定义一个一维数组的格式为:

<类型>  <数组名> [元素个数];

比如:int a[100];

表示定义了一个一维数组,数组里有100个格子,每个格子里可以存储一个int类型的变量。当然了,或许一维数组理解成一行表更加合适。需要注意的是,格子的编号是从099

所以,int a[100][100];就定义了一个二维数组,相当于一个100*100的表格。三维则继续推广。虽然没有维数的限制,但因为有程序使用的内存的限制(能使用的格子的数量的限制),维数一般不会太多。二维数组定义的时候,可以省略行数,但不能省略列数。

初始化的时候,同一行的值要用大括号括起来。

如果想知道一个数组中包含的元素个数,一般用下列语句:

sizeof(x)/sizeof(x[0]);

sizeofC语言提供的一元运算符,可以返回某个类型、变量或数组所占用内存的字节数。

 

复制数组:我们只能给数组中的某个格子复制。赋值语句形式如下:

a[n]=x; n为下标,必然是非负整数。二维和更高位的数组以此类推。 

数组元素的排序,用一篇专题来写。查找通常是二分查找。

 

6.2 一维数组的常用数据结构:

散列表——哈希表:利用数组下标,建立数值和下标的函数,就可以在需要的时候迅速找到数值。

缺点是有的时候会出现“哈希冲突”的现象。这种时候我们必须想办法(一般是另取特征编码)来

栈:先进后出。操作包括:栈的初始化、元素进栈、元素出栈、检查栈是否为空。栈说白了是一个思想,只是用数组来实现的,还是要做题才能掌握。可以简单理解为,把一个东西放到桶里,先放进去肯定在桶底,拿出来的时候先拿出桶的上部的东西。经典例题:括号匹配。

队:先进先出。操作和栈是一样的。队就好比火车过隧道,肯定是先进入隧道的那节车厢先出隧道。如果数据范围较大而前面的数据确定不再有用了,可以使用循环队列。优秀例题:N位超级质数。

 

6.3 字符串和字符数组

6.3.1 定义

用char定义的数组就是字符数组,双括号括起来的字符序列为字符串。

字符数组可以用字符串常量初始化,如:

char s[]="hangkonghangtian"

这种情况下,编译器会自动在'n'的后面加一个‘’。

没有字符串终止符''结尾的字符数组不能称为字符串,只能是字符数组保存了字符序列。

如:char s[]={'a','i','r'};

6.3.2 初始化

全局字符数组:未指定初始值的部分,默认为''。

局部数组:未指定初始值时,值未知;前面部分初始化,后面默认为''。

6.3.3 操作

字符串倒置:str_rev(s);

6.4 数组作为参数

函数参数是一维数组时,函数参数表中的数组括号为空:(int a[])

多维数组第一个下标的长度也不需要,但随后所有的下标都是必须的。

第7章 指针

常用的数据实体:简单变量和数组

变量有名称,类型,长度,值,地址等要素。数组是一串连续的地址。

7.1 指针

指针:数据实体的地址,其指向相应数据实体所在的内存空间。

地址的获取方法:

普通变量 &a; 数组元素 &a[1]; 函数和数组的名本身就是地址。 

定义指针的语法:<类型>*<变量名>

*说明名为<变量名>的变量是一个指针。

int *a; char *p; char *ap[20];//指向字符的指针构成的数组

7.2 作为函数参数的指针

通过指针类型的参数,可以同内部以间接访问的方式对外部变量进行操作。

注意,指针和数组在语法上都是等价的。

7.3 指针的运算

与指针相加的整数表示的是元素的个数。

*p++ 等价于 *(p++);(*p)++表示p先与*结合,++作用于p所指的变量。

属于同一数组的指针不能相加,但可以相减。

把0或NULL赋值给指针表明它是一个无效指针。

注意,指针所指向的变量如果没有初值,就必须用malloc()函数申请动态空间(并及时释放内存)。

7.4 字符指针与字符数组

字符指针可以用赋值号直接复制,字符数组不行;

赋了初值的字符数组可以改变自己的某个值,但指向一个字符串常量的指针不能改变字符串常量的值。

注意,数组名不是变量

7.5 一维数组指针与二维数组指针应用对比

int a[12]={}; int &p=a;

int b[3][4]={}; int (*pb)[4]=b; *pb是一个指向有四个值的数组的数组。

指针数组与二维数组的区别:

1.指针数组中只给指针分配了存储空间。其所指向的数据元素所需要的存储空间通过其他方式另行分配。

2.二维数组中每一行元素的个数相同,指针数组中各个指针指向的存储空间长度不一定相同。

3.二维数组中全部元素存储空间连续,指针数组中只有各个指针的存储空间连续。

7.6 名分问题

主语在后面:

指针函数:主语是函数,该函数返回一个指针

函数指针:主语是指针,指针本身指向一个函数。

指针数组:int *a[n];主语是数组,数组里每个元素是一个指针。

数组指针:int (*a)[n]; 主语是指针,这个指针指向一个数组。

第8章 编程思想

文章中处处体现的东西就不单独写啦。

这一章课件里有关于重定向的内容。

freopen("xxx.in","r",stdin);  freopen("xxx.out","w",stdout);

即可把标准输入输出定向到文件中。 

9章 结构和联合

9.1 结构

结构(struct):

定义一个结构类型的语法如下:

struct [<类型名>]{

<类型> <成员名称>;

};

比如定义一个结构:

struct innt{
    int a;
    bool flag;
};

这样定义的innt用法和intbool等类型没有区别。既可以定义变量,也可以作为数组类型:

innt qaq,kuku[100];

调用的时候就可以:

qaq.a=100; qaq.flag=1;
kuku[10].a=5; kuku[10].flag=0;

除此之外,还可以:

结构指针->成员名   或  (*结构指针).成员名

赋值的时候可以对成员逐一赋值,或者用已赋值的同类型的结构变量对它赋值。

9.2 用函数建立动态链表

有缘再写……

联合的定义语句和结构几乎相同,只需要把struct换成union。二者的区别在于结构中各个成员变量的存储空间是独立的,而联合中各个成员变量的存储空间是共享的。所以同一时间一个联合中只能有一个数据。编程中没遇到过,所以就不细说了。

原文地址:https://www.cnblogs.com/Shymuel/p/8449898.html