第五章、复杂数据类型

(数组、字符串、指针、结构体、枚举、共同体)

1.什么是数组?

概念:把具有相同类型的若干变量按有序的形式组织起来,这些按序排列的同类数据元素的集合称为数组;

按数组元素的类型不同,数组又可分为:

  1. 数值数组:用来存储数值得
  2. 字符数组:用来存储字符 ‘a’
  3. 指针数组:用来存放指针(地址)的
  4. 结构数组:用来存放一个结构体类型的数据

按维度分类:

  1. 一维数组
  2. 二维数组
  3. 多维数组

1.一维数组

概念:所有的元素都不是数组

使用流程:定义数组---->给数组初始化---->使用数组

定义:

数据类型 数组名[长度] ;

//int a[7];

1) 数组的类型实际上是指数组元素的取值类型。对于同一个数组,其所有元素的数据类型都是相同的。

2)第一个数组元素的地址是数组所占内存块的地址。

3) 数组名的书写规则应符合标识符的书写规定,命名不能相同。

4) 方括号中常量表达式表示数组元素的个数,如a[5]表示数组a有5个元素。但是其下标从0开始 计算。因此5个元素分别为a[0], a[1], a[2], a[3], a[4]

5) 不能在方括号中用变量来表示元素的个数,但是可以是符号常数或常量表达式。

6)定义数组不初始化存的是垃圾数,一旦有元素初始化,其他元素都赋值为0;


初始化:

定义:数据类型  数组名[长度]={元素1,元素2,…};

特点:

1)指定元素的个数的同时,对所有的元素进行显式的初始化

int nums[5] = {1,2,3,4,5};

2)指定数组的元素个数,对数组进行部分显式初始化 定义的同时对数组进行初始化,没有显式初始化的元素,那么系统会自动将其初始化为0

int nums[10] = {1,2};

3)不指定元素个数,定义的同时初始化,它是根据大括号中的元素的个数来确定数组的元素个数

int nums[] = {1,2,3,5,6};

4)指定元素个数,同时给指定元素进行初始化

int nums[5] = {[4] = 3,[1] = 2};

5)单个赋值:

数组名[角标]=值;

注意:一个长度为n的数组,最大下标为n-1;超过范围视为越界,会发生未知错误;

引用:

在C语言中只能逐个使用下标变量,而不能一次引用整个数组。

数组名[下标]

数组的遍历:通过循环访问数组的每一个元素。

 int a[]={,,,,,,,,};
//正序输出
for(int i=;i<;i++){
printf("%d\t",a[i]);
} //逆序输出
for(int i=;i>;i--){
printf("%d\t",a[i]);
}

存储方式:

假设有数组如下:
int x[]={1,2};
char ca[5]={‘a’,‘A’,‘B’,‘C’,‘D’};

注意:

  1. 计算机会给数组分配一块连续的存储空间
  2. 数组名代表数组的首地址,从首地址位置,依次存入数组的第1个、第2个....、第n个元素
  3. 每个元素占用相同的字节数(取决于数组类型)
  4. 并且数组中元素之间的地址是连续。

注意:字符在内存中是以对应ASCII值的二进制形式存储的,而非上表的形式。

地址:

连续的!

注意:在内存中,内存从大到小进行寻址,为数组分配了存储空间后,数组的元素自然的从上往下排列 存储,整个数组的地址为首元素的地址。

数组的长度计算:

数组的长度=数组的总字节数 / 数组的单个字节数

//count=sizeof(arr[10]) / sizeof(int)

五,有什么特点?

  • 1.数组必须要定义长度(正整数),定义时可初始化(长度必须是常量)或之后单独初始化.
  • 2.数组是有序的.每个数据都有角标.从0开始分配.角标不能>=数组长度.类型一致.
  • 3.数组有地址(数组名),里面的元素也有地址.数组当参数时(长度可省)传递的是地址.
  • 4.数组当参数传递时是指针类型.所以如果需要用数组长度要额外传递.

应用:

 使用选择排序实现一组数字的排序--大>>小
中心思想:把数组第一个元素的的角标设为最大值,于后面的数字相比较.找出最大值的角标,然后与第一个元素进行调换;找出一个最大值,同理循环 !!选择是把最大的一个数字一到最前面,所以y=x+..(确定最前面的数字)
#include<stdio.h>
int main()
{
int arr[]={,,,,,,,};
int maxzb=;
for (int x=;x<; x++) {
maxzb=x;//....?? for (int y=x+; y<;y++) { //y每次的循环初值!!!!!
if(arr[maxzb]<arr[y]){
maxzb=y;
}
}
printf("第%d次排序最大角标:%d\n",x,maxzb);
int temp=;
temp=arr[x];
arr[x]=arr[maxzb];
arr[maxzb]=temp;
for (int s=; s<; s++){ printf("%d\t",arr[s]);}//输出的是s.不是maxzb!!!
}
return ;
}

选择排序

 冒泡排序....最大数字移动最后,所以b=0每次从第一个开始.(确定最后一个数)
#include<stdio.h>
int main()
{
int arr[]={,,,,,,,,,};
for (int a=; a<; a++) {
for (int b=; b<-a; b++) {
if (arr[b]<arr[b+]) {
int temp=arr[b];
arr[b]=arr[b+];
arr[b+]=temp;
}
}
//printf("\n");
}
for (int c=; c<; c++) {
printf("%d\t",arr[c]);
} return ;
}

冒泡排序

数组用作函数参数有两种形式:

  • 一种是把数组元素(下标变量)作为实参使用;
  • 一种是把数组名作为函数;

1.数组元素就是下标变量,跟普通变量并无区别;

案例:

 判别一个整数数组中各元素的值,若大于0 则输出该值,若小于 等于0则输出0值
void nzp(int v){
if(v>)
printf("%d ",v);
else
printf("%d ",); }
int main( ){
int a[],i;
printf("input 5 numbers\n");
for(i=;i<;i++){
scanf("%d",&a[i]);
nzp(a[i]);
}
return ;
}

2.数组名作为函数参数

原理:

当数组名作函数参数时,实参与形参之间不是"值传递",而是"地址传递",所以传递时

实参数组名将该数组的起始地址传递给形参数组,两个数组共享一段内存单元,编译系统不再为形参数组分配存储单元。

案例:

数组a中存放了一个学生5门课程的成绩,求平均成绩。

float avg(float a[],int len){
//定义一个变量用于累加数组中元素的值
float sum=0.0f;
//循环累加
for (int i=; i<len; i++) {
sum+=a[i];
}
//返回平均成绩
return sum/len;
}
int main(int argc, const char * argv[]) {
//定义数组
float score[]={59.5f,60.0f,88.5f,91.0f,100.0f};
//获得数组长度
int len = sizeof(score)/sizeof(float);
//获得平均值
float av = avg(score,len);
printf("平均值:%.2f\n",av);
return ;
}

注意:

  1. 形参和相对应的实参都必须是类型相同的数组,否则会引起错误;
  2. 由于传递的是数组的首地址,所以要把数组长度传递进去;
  3. 形参可以不给出长度,或用变量表示个数:void nzp(int a[]) / void nzp( int a[], int n )
  4. 多维数组也可以作为函数的参数。在函数定义时对形参数组可以指定每一维的长度,也可省去 第一维的长度。因此,以下写法都是合法的:int MA(int a[3][10])  / int MA(int a[][10])
 

2.什么是二位数组?

概念:

是用来存储一组数组的容器,用于把同一类型的一组数组统一管理起来.数组是一种构造类型的数据。

二维数组可以看作是由一维数组的嵌套而构成的。设一维数组的 每个元素都又是一个数组,就组成了二维数组。

当然,前

C语言学习总结(三) 复杂类型的更多相关文章

  1. Go语言学习笔记三: 常量

    Go语言学习笔记三: 常量 定义常量 常量就是在声明后不能再修改的量. const x int = 100 const y string = "abc" const z = &qu ...

  2. Go语言学习(四)经常使用类型介绍

    1.布尔类型 var v1 bool v1 = true; v2 := (1==2) // v2也会被推导为bool类型 2.整型 类 型 长度(字节) 值 范 围 int8 1  128 ~ 12 ...

  3. 【原创】go语言学习(三)字符串串、时间和日期类型

    目录 1.字符串串原理理解析2. 时间类型3. 日期类型 字符串串原理理解析 1.字符串串底层就是⼀一个byte数组,所以可以和[]byte类型互相转换2.字符串串之中的字符是不不能修改的,那怎么修改 ...

  4. C 语言学习 第三次作业总结

    本次作业内容: For循环的使用 If判断语句的使用 常用数学运算表达式的使用 数学函数库中几个常见函数的使用及自我实现 将操作代码提交到coding 作业总结: For循环是C语言中一种基本的循环语 ...

  5. 【GO】GO语言学习笔记三

    7.数组: 几乎是最常用的数据类型了... 数组就是指一系列同一类型数据 的集合.数组中包含的每个数据被称为数组元素(element),一个数组包含的元素个数被称为数 组的长度. 常规的数组声明方法: ...

  6. [读书笔记]C#学习笔记三: C#类型详解..

    前言 这次分享的主要内容有五个, 分别是值类型和引用类型, 装箱与拆箱,常量与变量,运算符重载,static字段和static构造函数. 后期的分享会针对于C#2.0 3.0 4.0 等新特性进行. ...

  7. Swift学习(三)类型推导&基本运算&分支&循环

    一.Swift中类型推导&基本运算 Swift中类型推导 如果一个标识符在定义时有直接赋值,那么可以根据后面赋值的类型,来推导出前面标识符的类型,这样前面标识符的(:类型)可以省略 查看标识符 ...

  8. Go语言学习笔记(三) [控制结构、内建函数]

    日期:2014年7月21日   一.控制结构   1.Go中,只有几个控制结构,它没有do或者while循环,有for,灵活的switch语句和if,在switch中可以接受像for那样可选的初始化语 ...

  9. R语言学习 第三篇:数据框

    数据框(data.frame)是最常用的数据结构,用于存储二维表(即关系表)的数据,每一列存储的数据类型必须相同,不同数据列的数据类型可以相同,也可以不同,但是每列的行数(长度)必须相同.数据框的每列 ...

随机推荐

  1. 8个必备的PHP功能开发

    这篇文章主要介绍了8个必备的PHP功能开发,需要的朋友可以参考下 PHP开发的程序员应该清楚,PHP中有很多内置的功能,掌握了它们,可以帮助你在做PHP开发时更加得心应手,本文将分享8个开发必备的PH ...

  2. Winform DataTable 客户端操作数据

    //创建 DataTable DataTable dt = new DataTable(); dt.Columns.Add("ID"); dt.Columns.Add(" ...

  3. MyBatis+Spring 事务管理

                 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://kinglixing.blog.51cto.com/34 ...

  4. WPF组件开发

    在做组件之前,为了适应框架,我们需要有一个基类,并将这个基类打包成一个模板,让大部分组件去使用这个模板. 组件的基类就不多讲了,上篇文章中已经说过了.这是地址: http://www.cnblogs. ...

  5. iOS开发-javaScript交互

    前言 当前混合开发模式迎来了前所未有的发展,跨平台开发.热更新等优点决定了这种模式的重要地位.虽然前端界面在交互.动效等多方面距离原生应用还有差距,但毫无疑问混合开发只会被越来越多的公司接受.在iOS ...

  6. 15个Linux Yum命令实例--安装/卸载/更新

    在linux环境中, 安装, 卸载更新包是一个极为常见的操作.大部分的linux环境都提供了包的管理工具, 例如:apt-get, dpkg, rpm, yum等等. 一些Linux环境中,yum是默 ...

  7. List和ArrayList,LinkList的区别

    接口 List<E> 是一个接口: ArrayList<E> 是一个类:是一个实现了List接口的类,因此可以List里面定义的所有的方法都实现了. 1.ArrayList是实 ...

  8. linq按需查询

    将不确定变成确定~LINQ查询两种写法,性能没有影响,优化查询应该是“按需查询” 如果在linq中希望进行一对多的复合查询时,请直接在查询中使用join into,或者使用let 关键字,当然在建立实 ...

  9. 数据库性能高校:CPU使用过高(下)

    CPU使用率过高的常见原因 查询优化器会尽量从CPU,IO和内存资源成本最小的角度,找到最高效的数据访问方式.如果没有正确的索引,或者写的语句本身就会忽略索引, 又或者不准确的统计信息等情况下,查询计 ...

  10. 创建Java线程池

    线程池的作用: 线程池作用就是限制系统中执行线程的数量. 根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果:少了浪费了系统资源,多了造成系统拥挤效率不高.用线程池控制线程数量,其他线 ...