目录

1. C语言中的变量

2. 一维数组

2.1 数组的声明

2.2 数组初始化

2.3 对数组使用sizeof运算符

3. 多维数组

4. 常量数组

4. C语言数组类型

4.1 数组类型

4.2 typedef重定义数组类型的行为

5. C99中的变长数组(variable-length array, VLA)

6. 使用随机数


1. C语言中的变量

① 标量(scalar)

保存单一数据项

② 聚合(aggregate)变量

存储一组一组的数据

C语言中有:数组(array)和结构(structure)

2. 一维数组

2.1 数组的声明

声明数组需要指明数组元素的类型和数量

示例:int a[3];

特点:元素类型相同;连续存放

说明1:类型可以是任何类型,数量可以用任何整数常量表达式。用宏来定义数组的长度较好

注:一定要使用常量表达式是因为在编译的时候,数组的内存分配形式已经确定,一旦分配不可改变

说明2:数组相关特性

① 数组下标从0开始

② C语言不检查下标越界

③ a[i]是左值

④ 数组下标可以是任何整数表达式,表达式甚至可以有副作用

i = 0;
while (i < N)a[i++] = 0;

当数组下标有副作用时要注意:

i = 0;
while (i < N)a[i] = b[i++]; // 访问并修改了i 的值,会产生未定义的行为

改进方式:

for (i = 0; i < N; ++i)a[i] = b[i];

补充另一种拷贝数组的方式,

#include <string.h>// memcpy是一个底层函数,把字节从一个地方简单复制到另一个地方
memcpy(a, b, sizeof(a));

2.2 数组初始化

数组初始化式(array initializer)最常见格式:用大括号括起来的常量表达式列表

int a[5] = {1, 2}; //其他元素初始化为0

说明1:如果指定了完整初始化式,可以省略数组长度

说明2:初始化式只能是常量,不能是变量也不能是函数调用,因为数组的内存分配及初始化是在编译时进行的(下一点即将说明)

特别说明:GCC是不允许用变量初始化数组的,但VS2010竟然可以~~

还是GCC比较标准~~VS2010做了扩展~~

说明3:数组的编译方式

① 全局数组a存储在.data段

② 局部数组b在main函数的栈中处理

③ 只读全局变量num1在.rodata段,即只读数据段

④ 初始化的全局变量num2在.data段

⑤ 未初始化的全局变量num3在.bss段

说明4:可以使用memset函数初始化数组

#include <string.h>void *memset(void *s, int ch, size_t n);

函数功能:将s中前n个字节用ch替换并返回s

说明:memset是对较大的结构体或数组进行清零操作的最快方法

示例:

int a[30];
memset(a, 0, 30 * sizeof(int));

说明5:非法初始化

① 初始化式为空

int a[2] = {};

② 初始化式比要初始化的数组长

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

说明6:C99中的指定初始化式

适用场景:数组中只有相对较少的元素需要进行显式的初始化

int a[15] = {[2] = 48, [9] = 7, [12] = 29}; //指定初始化式的顺序无所谓

指定初始化式的的工作原理:编译器在处理初始化式列表时,会记录下一个待初始化的数组元素的位置。正常情况下,下一个元素是刚被初始化的元素后面的那个。但是,当列表中出现指定初始化式时,下一个元素会被强制为指示符对应的元素,即使该元素已被初始化

2.3 对数组使用sizeof运算符

int a[10];
sizeof(a);    //数组的大小
sizeof(a[0]); //数组元素的大小// 通过sizeof(a) / sizeof(a[0])可以得到数组长度
int i;
for (i = 0; i < sizeof(a) / sizeof(a[0]); ++i)// 问题:sizeof的返回值是size_t,为无符号类型,会有警告信息// 改进1
i < (int)(sizeof(a) / sizeof(a[0])// 改进2
// 之后还可以改进为带参数宏,参数为数组名
#define SIZE ((int)(sizeof(a) / sizeof(a[0])))// 改进3
// 调用式为SIZE(a)
#define SIZE(a) ((int)sizeof(a) / sizeof(a[0]))

3. 多维数组

int a[2][3];

C语言中按行主序存放多维数组,

初始化:嵌套一维初始化式,可简化省略内部括号。剩余未初始化的元素初始化为零,注意这里的零对不同类型数据有不同意义

处理:可以使用嵌套for循环处理二维数组

说明1:多维数组中也可使用C99中的指定初始化式

int a[2][3] = {[0][0] = 1, [1][1] = 2};

说明2:二维数组的使用场景

在使用二维数组表示批量数据的时候,我们总是将批量数据进行两次分类,第一次较大的分类结果作为第一个维度的个数,而第二次分类将第一次分类的结果再细分成具体的数据,数据的个数也就成了二维数组的第二个维度。(比如存储一个年级6个班,每个班30人的成绩数据)

4. 常量数组

const  int a[2] = {1, 2}; // 此时只能初始化不能赋值

const用于声明一些在程序执行过程中不会发生改变的参考信息数组

说明:常量数组中元素的正确理解是只读变量,编译器能够检测到直接修改某个元素的意图

① 直接修改,直接报错

② 间接修改

初始化pa时一定要有个(int *)的强制类型转换,否则会有警告

原因:常变量的指针也具有常属性,即cont int a,取其地址&a,该地址是具有常属性的(const int *)

但是注意,在C语言中仅给出警告,代码依然可以编译运行

4. C语言数组类型

4.1 数组类型

① C语言中的数组有自已特定的类型

数组的类型由数组元素类型和数组元素个数共同决定。例如,int array[5]的类型为int[5]

注意:一定要区分数组元素类型和数组类型!!!

②  数组名在表达式中被解释为数组首元素的地址,而&数组名代表整个数组(即编译器分配的整个数组空间)的首地址。从本质上来说,这两个指针的指针基类型不同

这里需要特别说明的是二维数组(更高维数组以此类推)

结果分析:p 为指向数组的指针,一次解引用后应该得到p 所指向的对象,而这个对象就是一个一维数组,对一维数组施加sizeof运算符自然得到整个数组的尺寸。这里还体现出一维数组名和指针之间的联系与区别

4.2 typedef重定义数组类型的行为

虽然可以用typedef定义新的数组类型,但是C语言函数中依然只是传递数组首地址

5. C99中的变长数组(variable-length array, VLA)

int n;
scanf("%d", &n);
int a[n];

说明:注意事项

① 变长数组没有静态存储期限static int[n];

原因:静态变量的值在编译时而不是运行时确定,但此时变长数组的长度尚未确定

② 变长数组没有初始化式

③ goto语句不能绕过变长数组的声明

原因:在程序执行过程中,遇到变长数组声明时通常就该为其分配内存空间了,用goto语句绕过变长数组的声明可能会导致程序对未分配空间的数组中的元素进行访问

6. 使用随机数

在使用随机数前要先初始化随机数种子

#include <stdlib.h>
#include <time.h>srand((unsigned)time(NULL)); //用当前时间初始化随机数种子
rand( ); //产生随机数,可对其取模以限定其范围

补充:time 函数的返回值为time_t 类型,追踪其定义,就是long int 类型

C程序设计语言现代方法08:数组相关推荐

  1. C程序设计语言现代方法12:指针和数组

    目录 1. 指针的算术运算 1.1 概述 1.2 C语言支持的算术运算类型 2. 指针的比较 3. 指针用于数组处理 4. 数组名与指针 4.1 用数组名作指针 4.2 数组取下标操作 4.3 惯用法 ...

  2. C程序设计语言现代方法18:声明

    目录 1. 声明的语法 2. 变量的性质 2.1 变量性质的构成 2.2 变量默认性质 2.3 修改变量默认性质 2.3.1 修改局部变量默认性质 2.3.2 修改全局变量默认性质 2.4 exter ...

  3. C程序设计语言现代方法17:指针的高级应用

    目录 1. 动态存储分配 1.1 malloc函数 1.2 calloc函数 1.3 realloc函数 1.4 free函数 2. 空指针NULL解析 2.1 NULL的定义形式 2.2 程序如何知 ...

  4. C程序设计语言现代方法15:编写大型程序

    目录 1. C语言程序一般构成 2. 源文件 2.1 源文件内容 2.2 将文件划分成多个源文件的优点 3. 头文件 3.1 包含头文件的3种方式 3.2 头文件共享内容 3.2.1 宏定义和类型定义 ...

  5. C程序设计语言现代方法13:字符串

    目录 1. 字符串字面量 1.1 定义 1.2 字符串字面量包含转义序列 1.3 延续字符串字面量 1.3.1 使用续行符 1.3.2 仅用空白字符分割字符串字面量 1.4 存储字符串字面量 1.5 ...

  6. C程序设计语言现代方法07:基本类型

    目录 1. 基本类型和构造类型 1.1 基本类型 1.2 构造类型 2. C语言两大类型(存储格式根本上不同) 3. 整数类型 3.1 6种有效组合 3.2 整数常量 3.3 整数溢出 3.4 读写整 ...

  7. Java程序设计语言基础04:数组

    目录 1. 数组基础 1.1 创建数组 1.2 使用数组 2. 数组的"名"与"实" 2.1 数组的"名" 2.2 数组的"实&q ...

  8. C程序设计语言现代方法14:预处理器

    目录 1. 预处理器工作原理 1.1 预处理器性质 1.2 预处理器主要功能 1.3 GCC编译过程及常用选项 1.3.1 GCC编译过程 1.3.2 编译选项实例 1.4 注意事项 2. 预处理指令 ...

  9. C程序设计语言现代方法11:指针

    目录 1. 指针变量 1.1 指针变量含义 1.2 int *p含义 1.3 指针变量4句圣经 2. 指针与函数 2.1 指针作为函数参数 2.2 指针作为函数返回值 3. 指针的四大用途 4. 什么 ...

最新文章

  1. 微信小程序隐藏标题栏navigationBar的方法
  2. ALV列(Column)换到行(Row) 之 列上限不固定篇
  3. Java8新特性 Optional类
  4. [php]Undefined offset: 0错误
  5. 基4fft算法的蝶形图_原地且自动整序的FFT算法
  6. C++ 读取文件操作
  7. win7工作组无法查看计算机名,WIN7下无法查看工作组计算机怎么办
  8. Opencv之通过url抓取图片并通过opencv可视化
  9. 超图高性能分布式渲染技术解密与应用
  10. 收藏!从十篇顶会论文解读计算机视觉的未来之路!
  11. 太极图正确画法_太极图唯一正确的画法
  12. Koo叔说Shader—最基本的Shader
  13. 别在直接背3500个英语单词了,支你一招,看过来
  14. scala编译常见错误
  15. 解决数字小键盘按shift+ 数字才可以使用的问题
  16. mc服务器常用指令_我的世界服务器指令大全 最新服务器指令汇总
  17. c语言中,关于延迟函数的理解
  18. 机械工程专业与c语言的联系,新工科背景下的机械专业C语言课程改革
  19. 最大公约数的几种求解及代码实现
  20. 软件著作权申请注意事项——所需材料[详细版,不断补充中]

热门文章

  1. Spring 源码解析 -- SpringWeb请求映射解析
  2. java 线程map_map集合分割以及多线程处理数据
  3. pom.xml中的dependency标签的classifier
  4. oracle 如何修改字符集 update prop,ORACLE 修改字符集
  5. mysql中用户线程作用,mysql用户线程的建立与用户线程的状态源码解析
  6. android 回退函数,android浏览器研究-回退和前进
  7. 集群虚拟服务器,Nginx集群 -LVS(Linux虚拟服务器)简介
  8. in作为介词的用法_(完整版)介词in重要用法归纳
  9. Vue -- 如何在 span 标签上实现一个点击事件
  10. java同类型同字段名称对象赋值