【C语言_数组_复习篇】

目录

一、数组的概念

二、数组的类型

三、一维数组

        3.1 一维数组的创建

        3.2 一维数组的初始化

        3.3 一维数组的访问

        3.4 一维数组在内存中的存储

四、二维数组

        4.1 二维数组的创建

        4.2 二维数组的初始化

        4.3 二维数组的访问

        4.4 二维数组在内存中的存储

五、变长数组 

六、字符串数组

        6.1 字符串数组的创建

        6.2 字符串数组的初始化

        6.3 字符串数组的输入

        6.4 字符串数组的输出

        6.5 字符串数组经典应用

七、指针数组

        7.1 指针数组

        7.2 指针数组模拟实现二维数组

八、函数指针数组

        8.1 函数指针数组

        8.2 函数指针数组的应用:转移表 

九、sizeof计算数组的大小


一、数组的概念

1. 数组是一组相同类型元素的集合,存放在数组内的值被称为数组元素,数组分为一维数组和多维数组,二维数组的每个元素是一维数组,三维数组的每个元素是二维数组,其他的数组依此类推,多维数组中最常见的数组是二维数组。

2. 数组的type有很多,如int、char、float、结构体等。后面所讲到的字符串数组,指针数组和函数指针数组也都只不过是不同类型数组而已,它们均可创建出一维、二维、多维的形式。

2. 数组的元素个数不能为0数组内的每个元素必须是相同类型的

二、数组的类型

1. 数组的类型是除掉数组名剩余的部分,例如,int arr[10],数组arr的类型是int [10]。

三、一维数组

3.1 一维数组的创建

1. 一维数组的语法格式:type arr_name[常量值];

2. type表示一维数组中的每个元素是什么类型的,arr_name表示一维数组的名称,[常量值]表示一维数组的大小。

#include <stdio.h>
int main()
{int arr1[10];//定义存放10个整型的一维数组char arr2[4];//定义存放4个字符的一维数组float arr3[6];//定义存放6个单精度浮点型的一维数组//...return 0;
}

3.2 一维数组的初始化

1. 一维数组的初始化分为完全初始化和不完全初始化。

2. 完全初始化:一维数组有多大,就初始化几个元素。

3. 不完全初始化:初始化的元素个数小于一维数组的大小,剩余未初始化的元素会默认初始化为0。

4. 初始化一维数组时,[ ]中的常量值也可以省略不写此时初始化几个元素,一维数组就为多大

#include <stdio.h>
int main()
{int arr1[10] = { 1, 2, 3, 4, 5, 6 ,7, 8, 9,10 };//完全初始化int arr2[10] = { 0 };//不完全初始化int arr3[] = { 1, 2, 3, 4 };//数组大小为4return 0;
}

3.3 一维数组的访问

1. 数组元素的访问需要用到下标引用操作符[ ],数组元素的下标都是从0开始,最大为sz-1

2. 访问时的要点:①知道需要的变量在哪个数组中②知道变量在该数组中的下标编号是多少

③连续输入或使用数组元素时创建循环变量利用 for 循环解决

//一维数组的输入和输出
#include <stdio.h>
int main()
{int arr[10] = { 0 };int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;//循环变量for (i = 0; i < sz; i++){scanf("%d", &arr[i]);printf("%d ", arr[i]);}return 0;
}

3.4 一维数组在内存中的存储

1. 一维数组在内存中连续存储,并且随着下标的增长地址由小到大变化

//验证一维数组在内存中的存储方式
#include <stdio.h>
int main()
{char arr[5] = { '0', '1', '2', '3', '4'};//字符数组,每个元素占一个字节int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;//循环变量for (i = 0; i < sz; i++){printf("arr[%d]=%p\n", i, &arr[i]);}return 0;
}

 

四、二维数组

4.1 二维数组的创建

1. 二维数组的语法格式:type arr_name[常量值1][常量值2];

2. type表示二维数组中的每个元素是什么类型的,arr_name表示二维数组的名称,[常量值1]表示二维数组中有几个一位数组(即几行)[常量值2]表示每个一维数组中有几个元素(即几列)

#include <stdio.h>
int main()
{int arr[3][5];//定义三行五列的整型二维数组char arr2[4][6];//定义4行6列的字符二维数组float arr3[2][4];//定义2行4列的浮点数二维数组//...return 0;
}

4.2 二维数组的初始化

1. 二维数组的初始化分为完全初始化和不完全初始化,一维数组的{}可打可不打不打{ }时元素按照排满一行再换一行的顺序摆放,打{ }时可以控制每行存哪些元素

2. 完全初始化:二维数组有几列几行,就初始化几列几行的元素。

3. 不完全初始化:初始化的元素个数小于数组大小(行*列),剩余未初始化的元素默认初始化为0。

4. 初始化二维数组时,常量值1也可以省略不写但常量值2必须写, 编译器会根据初始化内容判断二维数组有几行

#include <stdio.h>
int main()
{int arr1[3][4] = { { 1, 2, 3, 4 }, { 2, 3, 4, 5 }, { 3, 4, 5, 6 } };//完全初始化int arr2[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };//完全初始化int arr2[3][4] = { { 1 }, { 2, 3 }, { 4, 6, 8 } };//不完全初始化int arr3[3][4] = { 0, 1, 2 };//不完全初始化int arr4[][4] = { 1, 2 };//数组为1行4列int arr5[][4] = { { 1 }, { 3 }, { 2 , 5 } };//数组为3行4列return 0;
}

4.3 二维数组的访问

1. 二维数组的访问也要用到下标引用操作符[ ],二维数组的行标和列标都是0开始最大为sz-1

2. 访问时的要点:① 知道需要的变量在哪个数组中 ② 知道变量在该数组中的行标和列标是多少 ③ 连续输入或使用数组元素时创建循环变量利用嵌套 for 循环解决。

//二维数组的输入和输出
#include <stdio.h>
int main()
{int arr[3][4] = { 0 };int i = 0;//循环变量for (i = 0; i < 3; i++){int j = 0;//循环变量for (j = 0; j < 4; j++){scanf("%d", &arr[i][j]);printf("%d ", arr[i][j]);}//换行printf("\n");}return 0;
}

4.4 二维数组在内存中的存储

1. 二维数组和一维数组一样,在内存中连续存放随着下标的增长地址由小到大变化

//验证二维数组在内存中的存储方式
#include <stdio.h>
int main()
{char arr[2][3] = { { '1', '2', '3' }, { '2', '3', '4' }};//字符数组,每个元素占一个字节int i = 0;//循环变量for (i = 0; i < 2; i++){int j = 0;//循环变量for (j = 0; j < 3; j++){printf("arr[%d][%d]=%p\n", i, j, &arr[i][j]);}}return 0;
}

 

五、变长数组 

1. 概念:C99之前,数组的大小只能是常量。C99之后,引入了变长数组的概念,可以使用变量来指定数组的大小。但VS默认不支持C99中的变长数组,使用gcc编译器的DevC++支持,oj刷题的网站一般也是支持的。

2. 变⻓数组的根本特征数组⻓度只有运⾏时才能确定,所以变⻓数组不能初始化

3. 好处:当在开发时,没有确定好数组的大小,可以利用变长数组,待程序运⾏时再为数组分配精确的⻓度。

4. 注意:变⻓数组的意思是数组的⼤⼩是可以使⽤变量来指定的,在程序运⾏的时候,根据变量的⼤⼩来指定数组的元素个数,⽽不是说数组的⼤⼩是可变的。数组的⼤⼩⼀旦确定就不能再变化了。

六、字符串数组

6.1 字符串数组的创建

1. C语言中没有专门的字符串类型,如果要存放字符串可以用字符串数组存放(字符串数组本质是字符数组)。

2.  字符串数组的语法格式(和一维字符数组、二维字符数组一样):

     一位字符串数组:char arr_name[常量值]

     二维字符串数组:char arr_name[常量值1][常量值2]

6.2 字符串数组的初始化

1. 字符串数组的初始化分为完全初始化和不完全初始化,且均有两种写法,第一种是用单引号初始化,在字符串的末尾会自动存入\0,这种写法在定义字符串数组的大小时要考虑\0也是数组中的一个元素,第二种是用大括号的初始化,但不会自动存入\0,需要手动存入\0才能代表这是一个字符串数组,否则只能作为一个字符数组。(通常会用双引号的形式初始化)

2. 下面代码中仅展示一维字符串数组初始化形式,因为二维字符串数组很少用到。

#include <stdio.h>
int main()
{//一维字符串//方法一:用双引号初始化char arr1[4] = "abc";//完全初始化  a b c \0char arr2[4] = "ab";//不完全初始化 a b \0char arr3[] = "ab"//字符串数组大小为3//方法二:用大括号的初始化char arr4[4] = { 'a', 'b', 'c', '\0' };//完全初始化char arr5[4] = { 'a', 'b', '\0'};//不完全初始化char arr6[] = { 'a', 'b', '\0'};//字符串数组大小为3char arr7[4] = { 'a', 'b', 'c', 'd' };//不是字符串数组,因为数组中没有\0char arr8[4] = { 'a', 'b'};//不是字符串数组,因为数组中没有\0char arr9[] = { 'a', 'b'};//不是字符串数组,因为数组中没有\0                  return 0;
}

6.3 字符串数组的输入

1. 字符串数组的输入可以用scanf() 和 gets() 但两者是有区别的。 
2. scanf() 读取字符串时以空格为分隔,遇到空格就认为当前字符串结束了,所以无法读取含有空格的字符串。
3. gets() 认为空格也是字符串的一部分,只有遇到回车键时才认为字符串输入结束,所以在字符串数组输入时,最好用 gets()

#include <stdio.h>
int main()
{char arr1[10] = { '0'};//输入方法一:scanf("%s", arr1);//"hello world",只会读取hello//输入方法二:gets(arr1);//"hello world",全部读取return 0;
}

6.4 字符串数组的输出

1. 字符串数组的输出可以用用scanf() 和 gets() 但是有区别的。

2. printf():通过格式控制符%s 输出字符串,不能自动换行

3. puts():输出字符串并自动换行,该函数只能输出字符串。

#include <stdio.h>
int main()
{char arr1[10] = "abcde";//输出方法一:printf("%s\n", arr1);//不会自动换行,打印时加\n//输出方法二:puts(arr1);//会自动换行return 0;
}

6.5 字符串数组经典应用

//【实现:多个字符从两端移动,向中间汇聚】
//##########################
//Y########################!
//Yo######################!!
//You####################!!!
//You ##################!!!!
// ...
//You are the best!!!!!!!!!!#include <stdio.h>
#include <windows.h>
#include <stdlib.h>int main()
{char arr1[] = "You are the best!!!!!!!!!!";char arr2[] = "##########################";//计算数组arr2的元素个数int sz = sizeof(arr2) / sizeof(arr2[0]);//再屏幕上先打印数组arr2的内容printf("%s\n", arr2);int left = 0;int right = sz - 2;//字符串的末尾隐藏着一个\0while (left <= right){//睡眠1000毫秒Sleep(700);//sleep的第一个字母大写!arr2[left] = arr1[left];arr2[right] = arr1[right];//清屏system("cls");//system函数是库函数,执行系统命令,cls清理控制台屏幕//再次在屏幕上打印数组arr2printf("%s\n", arr2);//调整left++;right--;}return 0;
}

七、指针数组

7.1 指针数组

1. 指针数组就是存放指针的数组,数组中的每个元素都是指针(地址)。

2. 指针数组的类型由数组中每个指针解引用所指向变量的类型决定,我们可以根据需要自行选择创建一维指针数组还是二维指针数组,指针数组的创建方式、初始化、访问、存储方式和一维数组、二维数组讲述中的内容没有差别。

#include <stdio.h>
int main()
{int arr1[] = { 1, 2, 3 };int arr2[] = { 2, 3, 4 };int arr3[] = { 3, 4, 5 };int* arr[3] = { arr1, arr2, arr3 };//一维指针数组//由于数组名是数组首元素的地址,每个数组首元素的地址是int*类型的//所以arr指针数组语法中的tpye部分要写成int*return 0;
}

7.2 指针数组模拟实现二维数组

1. 模拟的⼆维数组,并⾮完全是⼆维数组,因为每⼀⾏的数据在内存中是⾮是连续的。

2. 下图代码的解释:parr是数组首元素的地址,而parr首元素的地址是数组arr1的地址,我们可以通过对parr+-整数拿到parr中每个元素的地址,即内部每个数组的地址,再通过对这些地址解引用拿到,每个内部数组首元素地址,最后通过首元素的地址偏移和解引用,找到parr内部数组中的每个元素,即有了 *(*(arr+i) + j) == parr[i][j] 。

#include <stdio.h>
int main()
{int arr1[] = {1,2,3,4,5};int arr2[] = {2,3,4,5,6};int arr3[] = {3,4,5,6,7};int* parr[3] = {arr1, arr2, arr3};//一位指针数组int i = 0;int j = 0;for(i=0; i<3; i++){for(j=0; j<5; j++){printf("%d ", parr[i][j]);}printf("\n");}return 0;
}

八、函数指针数组

8.1 函数指针数组

1. 函数指针数组是存放函数指针的数组函数指针数组里的元素全都是函数指针

2. 函数指针数组的类型由数组中每个元素的类型决定,但函数指针数组的创建写法比较独特,具体见下方代码。

    即要把函数指针类型中写指针名称的地方写成函数指针数组名+数组大小

3. 和指针数组一样我们可以根据需要自行选择创建一维函数指针数组还是二维函数指针数组,函数指针数组除创建方式写法有些独特外,其初始化、访问、存储方式和一维数组、二维数组中讲述的内容没有差别。

#include <stdio.h>int Add(int x, int y)
{//...return x + y;
}int Sub(int x, int y)
{//...return x - y;
}int Mul(int x, int y)
{//...return x * y;
}int main()
{int (*arr[3])(int, int) = { Add, Sub, Mul };//函数指针数组//arr是数组名,[3]表示数组大小//int ret = (arr+1)(2, 3);//err//int ret = (*(arr + 1))(2, 3);int ret = arr[1](2, 3);//下标直接访问printf("%d\n", ret);return 0;
}

8.2 函数指针数组的应用:转移表 

#include <stdio.h>int add(int a, int b)
{return a + b;
}int sub(int a, int b)
{return a - b;
}int mul(int a, int b)
{return a * b;
}int div(int a, int b)
{return a / b;
}int main()
{int x, y;int input = 1;int ret = 0;int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表do{printf("*************************\n");printf(" 1:add 2:sub \n");printf(" 3:mul 4:div \n");printf(" 0:exit \n");printf("*************************\n");printf("请选择:");scanf("%d", &input);if ((input <= 4 && input >= 1)){printf("输⼊操作数:");scanf("%d %d", &x, &y);ret = p[input](x, y);printf("ret = %d\n", ret);}else if (input == 0){printf("退出计算器\n");}else{printf("输⼊有误\n");}} while (input);return 0;
}

九、sizeof计算数组的大小

1. sizeof是专门计算变量或类型所占空间大小的一个关键字,计算结果的单位是字节,sizeof不会执行( )内的任何运算和函数调用。

2. sizeof(数组名)计算的是整个数组的大小,这里的数组名不再是数组首元素的地址。

3. 计算一维数组元素个数:int sz = sizeof(arr) / sizeof(arr[0]);利用整个数组的大小除以单个数组元素的大小,得到的就是数组大小,打印时占位符%d不行就用%zd。

4. 计算二维数组元素个数:int sz = sizeof(arr) / sizeof(arr[0][0]);

5. 使用的好处:方便修改和利用。

6. 好习惯:定义和初始化一维数组后,下面一行立即写上用sizeof计算出的一维数组元素个数。

 本篇已完结。。。。。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/755907.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android 开发 地图 polygon 显示信息

问题 Android 开发 地图 polygon 显示信息 详细问题 笔者进行Android项目开发&#xff0c;接入高德地图绘制区域后&#xff0c;需要在指定区域&#xff08;位置&#xff09;内显示文本信息&#xff0c;如何实现 实现效果 解决方案 代码 import com.amap.api.maps.model.T…

Jenkins实现CICD(3)_Jenkins连接到git

文章目录 1、如何完成上述操作&#xff0c;并且不报如下错&#xff1a;2、连接不上git&#xff0c;操作如下&#xff1a;3、将上边产生的3个文件拷贝到&#xff1a;C:\Windows\System32\config\systemprofile\.ssh4、新建下图凭证&#xff1a;创建步骤&#xff1a; 5、公钥填到…

vue3 搜索框 相关搜索内容 搜索词变色

html <!-- 搜索框 --> <div class"input"><input type"text" v-model"search_content" input"replace_text(search_content)"focus"search_show true, replace_text(search_content)" blur"search_s…

NCV4264-2ST50T3G芯片中文资料PDF数据手册引脚图规格书参数产品手册价格图片

产品概述&#xff1a; NCV4264-2 在功能和引脚上都与 NCV4264 兼容&#xff0c;具有较低的静态电流消耗。 其输出级提供 100 mA&#xff0c;输出电压精度为 /-2.0%。 100 mA 负载电流下的最大漏电压为 500 mV。它具有针对 45 V 输入瞬变、输入电源逆向、输出过电流故障和超高裸…

c语言(数据在内存中的存储)

1. 整数在内存中的存储 整数的2进制表⽰⽅法有三种&#xff0c;即原码、反码和补码 三种表⽰⽅法均有符号位和数值位两部分&#xff0c;符号位都是⽤0表⽰“正”&#xff0c;⽤1表⽰“负”&#xff0c;⽽数值位最 ⾼位的⼀位是被当做符号位&#xff0c;剩余的都是数值位。 正整…

可视化工具 Another-Redis-Desktop-Manager 的安装与使用

一,下载安装 1.简介 Redis是一种快速、高效的NoSQL数据库&#xff0c;广泛用于缓存、会话管理、消息队列等领域。为了更方便地管理Redis实例、监控Redis性能、执行Redis命令、查看Redis数据&#xff0c;许多开发者使用可视化管理工具。而其中&#xff0c;Another Redis Deskt…

关于Ansible的模块 ①

转载说明&#xff1a;如果您喜欢这篇文章并打算转载它&#xff0c;请私信作者取得授权。感谢您喜爱本文&#xff0c;请文明转载&#xff0c;谢谢。 什么是Ansible模块 在Linux中&#xff0c;bash无论是在命令行上执行&#xff0c;还是在bash脚本中&#xff0c;都需要调用cd、l…

理论学习:outputs_cls.detach()的什么意思

在PyTorch中&#xff0c;.detach()方法的作用是将一个变量从当前计算图中分离出来&#xff0c;返回一个新的变量&#xff0c;这个新变量不会要求梯度&#xff08;requires_gradFalse&#xff09;。这意味着使用.detach()方法得到的变量不会在反向传播中被计算梯度&#xff0c;也…

知识宣传手册该怎么制作?

知识宣传手册该怎么制作&#xff1f; 制作知识宣传手册是一个很好的方式来传播知识&#xff0c;提高公众对特定主题的了解。它们不仅能帮助我们传播重要信息&#xff0c;还能激发人们的求知欲&#xff0c;推动社会的进步。那么&#xff0c;如何制作一份引人入胜的知识宣传手册…

C++_day6:2024/3/18

作业1&#xff1a;编程题&#xff1a; 以下是一个简单的比喻&#xff0c;将多态概念与生活中的实际情况相联系&#xff1a; 比喻&#xff1a;动物园的讲解员和动物表演 想象一下你去了一家动物园&#xff0c;看到了许多不同种类的动物&#xff0c;如狮子、大象、猴子等。现在…

C语言笔记:函数与程序结构

目录 ACM金牌带你零基础直达C语言精通-课程资料 一.作用域的基本概念 二.函数 1. 函数的定义和使用 2.为什么一定要有函数结构 3.形参与实参 4.函数的声明和定义 5.递归函数 此代码中递归函数执行流程&#xff1a; 练习&#xff1a;求斐波那契数列第n项的值&#xff1a; 欧几里…

day-24 跳跃游戏 III

思路&#xff1a;dfs方法&#xff0c;从开始节点开始进行深度优先遍历&#xff0c;利用一个数组vis[]记录该位置是否被访问过&#xff0c;如果遍历到一个已经访问的位置&#xff0c;返回false 如果遍历到某位置的值为0&#xff0c;返回true code: class Solution {public boo…

json-server库的使用,实现数据模拟

项目目录 安装 npm i -g json-server0.17.4 启动单个json服务&#xff0c;在cookbook目录下执行命令&#xff1a; json-server ./mock/a.json -p 9000 待实现 使用0.17.4版本即可。

基于php高校选课系统设计与实现flask-django-python-nodejs

接着&#xff0c;本论文将设计一个基于Web的高校选课系统&#xff0c;并通过详细的需求分析和系统架构设计来解决现有系统中存在的问题。系统的开发将采用目前流行的Web技术和数据库技术&#xff0c;并考虑系统的灵活性、安全性和易用性。最后&#xff0c;本论文将对开发出的系…

基于java的宠物信息交流平台设计(含源文件)

随着世界经济信息化、全球化的到来和互联网的飞速发展&#xff0c;推动了各行业的改革。若想达到安全&#xff0c;快捷的目的&#xff0c;就需要拥有信息化的组织和管理模式&#xff0c;建立一套合理、动态的、交互友好的、高效的“多鱼”旧物交易平台。当前的信息管理存在工作…

A Decade’s Battle on Dataset BiasAre We There Yet?

一些废话&#xff1a;好久没有做论文阅读系列的博客了&#xff0c;之前放弃是因为逐渐繁忙的学业以及论文那边实验非常的揪心&#xff0c;自己其实也看了很多论文&#xff0c;但是记的笔记不足以帮助到大家&#xff1b; 论文下载地址&#xff1a; https://arxiv.org/pdf/2403.…

组合000

题目链接 组合 题目描述 注意点 1 < n < 201 < k < n可以按 任何顺序 返回答案 解答思路 使用深度优先遍历根据传入的深度depth寻找相应的组合。因为组合中的元素不能重复&#xff0c;从小到大选择元素&#xff0c;在深度优先遍历时&#xff0c;根据上一次进入…

堆(数据结构)

堆的概念及结构 如果有一个关键码的集合K { &#xff0c; &#xff0c; &#xff0c;…&#xff0c; }&#xff0c;把它的所有元素按完全二叉树的顺序存储方式存储在一个一维数组中&#xff0c;并满足&#xff1a; < 且 < ( > 且 > ) i 0&#xff0c;1&#xff…

深入解析分布式限流

一、概述 1.1 主要解决的问题 访问请求流量远远大于服务器的负载&#xff0c;致使服务器宕机&#xff0c;导致整个服务的不可用&#xff1b;- 限流当前服务调用其他服务&#xff0c;其他服务不可用&#xff0c;导致当前服务的调用一直超时&#xff0c;进而当前服务的线程资源耗…

3D产品配置器有哪些实际的商业应用场景?

3D产品配置器在商业领域有着广泛的应用场景&#xff0c;它们不仅能够提升客户体验&#xff0c;还能帮助企业优化内部流程和加速产品开发。以下是一些具体的商业应用实例&#xff1a; 1、在线定制和销售&#xff1a;3D产品配置器允许客户在购买前根据自己的喜好定制产品&#x…