一.什么是数组

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

二、一维数组

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. 【译】ConfigureAwait FAQ

    .NET 在数年前就在语言和库中添加了 async/await.在那段时间里,它像野火一样蔓延开来,不仅在 .NET 生态系统中,而且在无数其他语言和框架中被复制.在 .NET 中也看到了大量的改进, ...

  2. 部署kubernetes-dashboard并配置ServiceAccount和登录鉴权

    "种草" kubernetes-dashboard 安装部署dashboard 创建用于登录面板的ServiceAccount 权限控制 "种草" kubern ...

  3. Vue3实现组件级基类的几种方法

    Vue3的组件有三种代码组织方式 纯Option API (不含setup) option API + setup 纯 setup (即composition API) 对于这三种形式,设置基类的方法 ...

  4. ubuntu20安装docker、redis、mysql及部署net6应用

    一.更新系统软件包索引 sudo apt update 二.安装docker sudo apt install docker.io 三.在docker中安装Mysql 拉取mysql镜像 docker ...

  5. Rust中的函数指针

    什么是函数指针 通过函数指针允许我们使用函数作为另一个函数的参数.函数的类型是 fn (使用小写的 "f" )以免与 Fn 闭包 trait 相混淆.fn 被称为 函数指针(fun ...

  6. 用vue+elementui写了一个图书管理系统

    用vue+elementui写了一个图书管理系统 转载自公号:java大师 目前是指一个纯前端的展示,后端还在开发中,前端接口是通过json-server模拟的 用到的技术栈 1.vue.js 2.e ...

  7. vue+vant项目中 rem适配配置

    vant rem适配,需要安装两个插件 postcss-pxtorem 是一款 postcss 插件,用于将单位转化为 rem lib-flexible 用于设置 rem 基准值 postcss-px ...

  8. 2023-03-22:给定一个字符串str, 如果删掉连续一段子串,剩下的字符串拼接起来是回文串, 那么该删除叫做有效的删除。 返回有多少种有效删除。 注意 : 不能全删除,删成空串不允许, 字符串长

    2023-03-22:给定一个字符串str, 如果删掉连续一段子串,剩下的字符串拼接起来是回文串, 那么该删除叫做有效的删除. 返回有多少种有效删除. 注意 : 不能全删除,删成空串不允许, 字符串长 ...

  9. 2022-02-04:组合总和 Ⅳ。 给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 题目数据保证

    2022-02-04:组合总和 Ⅳ. 给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target .请你从 nums 中找出并返回总和为 target 的元素组合的个数. 题目数据保证 ...

  10. flask之数据模型flask-sqlalchemy

    一.安装数据库连接依赖包 pip install flask-sqlalchemy pip install pymysql 二.项目配置 app/__init__.py from flask_sqla ...