一.什么是数组

数组其实装一些特定的数据的容器,而这个容器是有规定的长度的。并且特定数据和长度都是我们规定的。

二、一维数组

1.一维数组创建

类型名 数组名[数组的长度];
类型名 数组名[] = {value, value};
类型名 数组名[数组的长度] = {value, value};

第一种方式是动态创建。数组的长度有 [] 里的参数决定。

第二种创建方法是静态创建。数组的长度由后面的初始值的个数决定。

第三种方法是不完全初始化,也有可能是完全初始化。得看数组的长度和初始值的内容长度。如果说是使用不完全初始化,那么剩下的内容以0来占位。

2.一维数组的使用

2.1 索引值

如果我们需要查看数组中里面元素的内容,可以使用索引值来进行查看。

索引值从0开始,一直到数组长度-1。

使用方法:

数组名[索引值];

例如:查看数组arr里面索引值为2的内容

int arr[] = {1,2,3,4,5,6,7};
printf("%d\n", arr[2]);

2.2 遍历数组

本质上就是把数组中的所有内容全部输出一遍。

利用的是索引值的变化,找到索引值的最大值,然后索引值进行变化,从而找到数组中的所有元素。

int main(){
int arr[] = {1,2,3,4,5,6,7};
int i;
for (i = 0; i < 7; i++){
printf("%d\t", arr[i]);
}
}

2.3 如何使用sizeof()计算出数组的长度

首先需要知道数组在空间中所占的大小为多少,数组在空间中所占的大小由数组的类型和数组的长度组成,也就是说:

数组所占字节数=数组的类型所占字节数*数组的长度

sizeof(数组名) 可以直接得到数组所占的字节数,而数组只能存放一种类型的数据,而数组索引值为0的这个元素是必须存在的,无论你的数组长多少,这个索引值为0的元素必须存在,如果这个索引值不存在,那么这个数组就没有存在的意义了。

而我们可以通过索引值为0这个位置的元素得到这个数组它每一个空间所占的字节数,所以我们可以通过sizeof()计算出这个数组的长度。

数组的长度=数组所占字节数/数组的类型所占字节数

代码表示如下:

int arr[] = {1,2,3,4,5,6,7};
printf("%d\n", sizeof(arr)/sizeof(arr[0]));

三、二维数组

二维数组其实本质是在一个数组中存放一个数组。

1.二维数组的创建

类型名 数组名[外部数组的长度][内部数组的长度];
类型名 数组名[][内部数组的长度] = {value,value};
类型名 数组名[][内部数组的长度] = {{value}, {value}};

第一种创建方法是动态创建。

第二种创建方法是静态创建,只需要规定内部数组的长度,然后计算机会自动计算出外部数组的长度,但是不能只写外部数组的长度,这样是不可以的。

第三种创建方法是完全初始化或者不完全初始化,在初始化值中,如果有大括号,就代表着一个数组,而如果你这个大括号里面元素的个数和内部数组的长度不匹配,那么就会补上0

这种方法创建的时候,外部数组的长度由初始值中的大括号来决定。

2.二维数组的使用

2.1 找到数组中的内容

其实也是使用索引值,这里的索引值要注意,需要写上两个。

比如说需要找到二维数组中第1个数组里的第2个元素:

int arr[][3] = {1,2,3,4,5,6,7,8,9,10};
printf("%d\n", arr[1][2]);

2.2 遍历二维数组

这里不能直接使用sizeof()直接计算出数组的长度。除非你知道外部数组的长度或者内部数组的长度。

(内层数组的长度 * 内层数组每块空间的类型所占的字节数)*外层数组的长度 = 这个二维数组所占的字节数

如果你得到了其中一个才可以使用sizeof()进行推断。

//假如知道外部数组的长度=5
for (i = 0; i < 5; i++){
for (j = 0; j < sizeof(arr)/(5*arr[0][0])){
printf("%d\t", arr[i][j]);
}
}
//假如知道内部数组的长度=3
for (i = 0; i < sizeof(arr)/(3*arr[0][0]); i++){
for(j = 0; j < 3; j++){
printf("%d\t", arr[i][j]);
}
}

上面的方法是知道一个值才能使用上面的方式,如果不知道一些已知条件就不能使用上面的方式进行计算。

四、数组深层理解

数组其实是一块连续的空间,所以我们想要为数组规定一下它的长度,如果不规定会导致数组在开辟空间的时候不知道开辟多大的空间。

1.数组的地址

数组的地址是首元素的地址值,而输出数组的地址可以直接写数组名

int arr[5];
printf("%d", arr);

不需要使用&的方式。需要记住:数组的地址是首元素的地址。下面的代码可以验证

int main(){
int arr[] = {1,2,3,4,5};
if (arr == &arr[0])
printf("地址一样");
else
printf("地址不一样");
return 1;
}

输出的内容是一样的。

2.&数组名

我们知道数组名得到的就是数组的地址,而数组中第一个元素的地址也是数组的地址,那么直接&数组名得到的内容是什么呢?

直接&数组名得到的是整个数组的地址,虽然说这个地址和我们的数组首元素的地址一样,但是代表的内容确是不一样的,因为它是代表整个数组的长度,如果使用这个地址+1,那跳过的是一个数组的长度。

例如现在有一个数组arr,它的长度为5

int arr[5];
printf("&arr=%p\n", &arr);
printf("&arr+1=%p\n", &arr + 1);

首先先输出一下这个数组的地址,得到的结果为:0061FE8C,后面的输出是将整个数组的地址+1,得到的结果为:0061FEA0,会发现上面的结果和下面的结果相差了20个字节,而我整个数组是20个字节,所以可以知道当我们&数组名后得到的是整个数组的地址,并且使用这个地址加一个常数,那跳过的是整个数组。

3.数组作为函数的参数

在使用数组的时候需要将数组作为函数的参数传入进函数中,所以就得对传入的数组进行操作,这里有两种方式

3.1 数组作为函数的参数

这种方式的写法如下:

void test(int arr[]){}

而调用这个函数的时候是直接写数组名

int main(){
int arr[5];
test(arr);
}

然后就可以进行使用了。这种方式是将你传入的这个数组中第一个元素的地址传入进test中的形参arr中,也就是arr是数组中的第一个元素,然后对这个数组进行操作本质上也是操作main函数中的arr

因为函数中操作的地址和这个数组的地址是一样的,所以操作的时候也是操作数组的空间。

3.2 数组以指针的形式

其实使用的数组连续空间的特征和地址的加运算。

现在有下面的这个函数

void test(int* a){}

调用的时候直接传入这个数组的地址,但不是整个数组的地址,这种方法和上面的方法是一样的,使用方法也是一样的。都是第一个元素的地址。

4.数组使用非索引的方式

在使用数组的时候也可以不使用索引的方法得到元素,因为知道,数组名是首元素的地址,而地址可以使用解引用的方式,所以这里可以使用数组地址加上地址的加运算和解引用来操作,如下代码:

int main(){
int arr[] = {1,2,5,4,5};
printf("%d", *(arr + 2));
}

通过数组名进行加操作,因为数组名就是地址,所以直接用地址进行加操作,操作完之后需要使用解引用,将地址所对应的内容解出来。

5.数组表达字符串

字符串这个并不是一个类型,在其它语言中会为其封装,而C语言中并没有这个类型,那如何表示字符串呢?

首先我们要知道字符串是一堆字符连起来,所以叫做字符串,那通过一些数据类型将字符连在一起就可以变成字符串了。

那么如何做到呢?这里就需要使用到数组了,因为数组是一个连续的空间,可以很好的让这些字符串连在一起。

5.1 创建字符串

创建的方式很简单,就是创建数组的方式

char str1[] = {'H', 'e', 'l', 'l', 'o'};
char str2[] = "Hello";

str1str2这两种创建方法都是可以的,但是他们之间是有区别的,str1中的字符使用%s进行输出的时候后面会出现一些乱码(乱码不固定,不一定会出现)

char str1[] = {'H', 'e', 'l', 'l', 'o'};
printf("%s", str1);

str2使用%s输出的时候并不会出现乱码,因为直接使用""括起来的字符的后面会默认加一个\0,而%s进行输出的时候遇到\0就会结束。

这两种方法创建出来的长度也不同,str1创建出来的字符串长为5,而str2创建出来的字符串长度为6,因为str2的后面有一个\0

C语言基础--数组详细说明的更多相关文章

  1. day05<Java语言基础--数组>

    Java语言基础(数组概述和定义格式说明) Java语言基础(数组的初始化动态初始化) Java语言基础(Java中的内存分配以及栈和堆的区别) Java语言基础(数组的内存图解1一个数组) Java ...

  2. Java语言基础(数组)

    Java语言基础(数组概述和定义格式说明) A:为什么要有数组(容器) 为了存储同种数据类型的多个值 B:数组概念 数组是存储同一种数据类型多个元素的集合.也可以看成是一个容器. 数组既可以存储基本数 ...

  3. C语言基础--数组及相关

    概念: 一堆相同类型的数据的有序集合 格式: 元素类型  数组名称[ 元素个数 ] 定义数组: // 定义了一个名称叫做scores的数组, 数组中可以存放3个int类型的数据 ]; // 只要定义一 ...

  4. iOS开发环境C语言基础 数组 函数

    1 求数组元素的最大值 1.1 问题 创建程序,实现查询数组中最大值的功能,需求为:创建一个长度为10的数组,数组内放置10个0~99之间(包含0,包含99)的随机数作为数组内容,要求查询出数组中的最 ...

  5. [C语言基础] 数组与指针之间的引用

    通过指针引用数组,通过数组引用指针,你搞明白了么?通过下面3种情形来了解一下数组和指针 Case 1. unsigned char arry[10]; unsigned char *ptr; unsi ...

  6. C语言基础--数组

    数组 概念:在内存中连续存储的具有相同数据类型的一组数据的集合. 注意: 数组中的数据类型必须都是一致的 数组在内存中必须是连续的存储空间 定义数组时候的注意事项: 定义数组的时候,[]里面的值不能是 ...

  7. C#语言基础——数组

    数组 一.一位数组 数组初始化,创建数组,数组长度为5 int[] array = new int[5]; array[0] = 1; array[1] = 2; array[2] = 3; arra ...

  8. C语言基础:数组 分类: iOS学习 c语言基础 2015-06-10 21:40 7人阅读 评论(0) 收藏

    数组:是由一组具有相同数据类型的数据组合而来. 数组定义:元素类型修饰符 数组名[数组个数]={元素1,元素2....};  int arr[ 2 ]={1,2};    //正确 int arr[ ...

  9. R语言基础-数组和列表

    数组(array) 一维数据是向量,二维数据是矩阵,数组是向量和矩阵的直接推广,是由三维或三维以上的数据构成的. 数组函数是array(),语法是:array(dadta, dim),当中data必须 ...

  10. 【搬砖】安卓入门(4)- Java开发编程基础--数组

    05.01_Java语言基础(数组概述和定义格式说明)(了解) A:为什么要有数组(容器) 为了存储同种数据类型的多个值 B:数组概念 数组是存储同一种数据类型多个元素的集合.也可以看成是一个容器. ...

随机推荐

  1. 任务拆解,悠然自得,自动版本的ChatGPT,AutoGPT自动人工智能AI任务实践(Python3.10)

    当我们使用ChatGPT完成某些工作的时候,往往需要多轮对话,比如让ChatGPT分析.翻译.总结一篇网上的文章或者文档,再将总结的结果以文本的形式存储在本地.过程中免不了要和ChatGPT" ...

  2. 可视化大屏的终极解决方案居然这么简单,vue-autofit一行全搞定!

    可视化大屏适配/自适应现状 可视化大屏的适配是一个老生常谈的话题了,现在其实不乏一些大佬开源的自适应插件.工具但是我为什么还要重复造轮子呢?因为目前市面上适配工具每一个都无法做到完美的效果,做出来的东 ...

  3. 我的第一个项目(十二) :分数和生命值的更新(后端增删查改的"改")

    好家伙,写后端,这多是一件美逝. 关于这个项目的代码前面的博客有写  我的第一个独立项目 - 随笔分类 - 养肥胖虎 - 博客园 (cnblogs.com) 现在,我们登陆进去了,我开始和敌人战斗,诶 ...

  4. Python tkinter的简单使用,在绘布上播放GIF和图片

    Python tkinter的简单使用,在绘布上播放GIF和图片 文章目录 Python tkinter的简单使用,在绘布上播放GIF和图片 前言 一.tkinter 的简单组件以及pack(),gr ...

  5. Prism Sample 7 Modules LoadManual

    这种模块是手动载入的,需要的时候手动加载. 在app.xaml.cs中注册为按需加载,代码 protected override void ConfigureModuleCatalog(IModule ...

  6. Django笔记三十七之多数据库操作(补充版)

    本文首发于公众号:Hunter后端 原文链接:Django笔记三十七之多数据库操作(补充版) 这一篇笔记介绍一下 Django 里使用多数据库操作. 在第二十二篇笔记中只介绍了多数据库的定义.同步命令 ...

  7. ai问答:vue3+pinia+WebSocket 封装断线重连(实战)

    把socket实例 挂载到全局 为方便梳理,请忽略typescript # main.ts import {createApp} from 'vue' import App from './App.v ...

  8. 2021-11-28:有一棵树,给定头节点h,和结构数组m,下标0弃而不用。 比如h = 1, m = [ [] , [2,3], [4], [5,6], [], [], []]

    2021-11-28:有一棵树,给定头节点h,和结构数组m,下标0弃而不用. 比如h = 1, m = [ [] , [2,3], [4], [5,6], [], [], []], 表示1的孩子是2. ...

  9. ubuntu搜狗输入法显示简体中文,输入却是繁体中文问题解决方案

    一.现场重现 我的ubuntu版本是20.04,搜狗输入法版本是2.4.在输入的时候发生了如下场景: 明明输入法上是简体中文,可是打出来就变成了繁体中文! 二.解决方案 1.尝试 网上许多答案都是按下 ...

  10. C# decimal double 获取一组数字 小数点后最多有几位

    有一组数字,想判断一组数字中最多的有几位小数,乘以10的指定幂,转为整数,此处教大家一个高级的写法,拒接无脑for循环 decimal: decimal[] numbers = new decimal ...