初始C语言 - 数组(一维数组、二维数组、数组越界、数组传参)
目录
一、一维数组的创建和初始化
1、数组的创建
2、 数组的初始化
3.一维数组的使用
数组通过下标来访问
总结:
1. 数组是使用下标来访问的,下标是从0开始。
2. 数组的大小可以通过计算得到。
4、一维数组在内存中的存储
二、 二维数组的创建和初始化
1.二维数组的创建
2.二维数组的初始化
二维数组的初始化:行可以省略,列不能省略
3.二维数组的使用
二维数组的使用也是通过下标的方式。
4、二维数组在内存中的存储
三、 数组越界
数组的下标是有范围限制的。
四、数组作为函数参数
错误设计(冒泡排序):
错误原因:误以为传递的参数时整个数组,其实时数组首元素地址
引出了一个问题:
调试之后可以看到 bubble_sort 函数内部的 sz ,是1。
难道数组作为函数参数的时候,不是把整个数组的传递过去?
数组传参规则:
1. sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数
组。
2. &数组名,取出的是数组的地址。&数组名,数组名表示整个数组。
正确设计 - 冒泡排序
一、一维数组的创建和初始化
1、数组的创建
数组是一组相同类型元素的集合。type_t arr_name [const_n];//type_t 是指数组的元素类型//const_n 是一个常量表达式,用来指定数组的大小
数组什么时候创建?注:数组创建,在C99标准之前, [] 中要给一个常量才可以,不能使用变量。在C99标准支持了变长数组的概念,数组的大小可以使用变量指定,但是数组不能初始化。所以:代码2是错误的例子
//代码1
int arr1[10];
//代码2 - 错误示范
int count = 10;
int arr2[count];//数组时候可以正常创建?
//代码3
char arr3[10];
float arr4[1];
double arr5[20];
试了一下,此环境下不支持C99标准,可以从这个n下面的红波浪线看出来,报错了,这里的数组[]
里面只能是常量!!!!
2、 数组的初始化
数组的初始化是指:在创建数组的同时给数组的内容一些合理初始值(初始化)
初始化有完全初始化和不完全初始化
完全初始化:数组指定了明确的元素个数,且每个元素空间里都有元素
不完全初始化:数组指定了元素个数,但元素空间有剩余,没有占满整个数组空间,默认补0
int main()
{//完全初始化int arr1[10] = { 1,2,3,4,5,6,7,8,9,10 };//不完全初始化,剩余的默认初始化为0int arr2[10] = { 1,2,3,4,5 };//1 2 3 4 5 0 0 0 0 0 int arr3[10] = { 0 };// 0 0 0 0 0 0 0 0 0 0 //字符数组:可以放单个字符char ch1[5] = { 'a','b',99 };//a b c 0 0 0 //可以放字符串char ch2[10] = "abcdef";//数组初始化,可以不知道数组元素大小,但必须有数组内容,数组的大小会根据数组内容来确定char ch3[] = "abc";char ch4[] = { 'a','b','c' };printf("%s\n", ch3);//abc //遇到\0就结束了printf("%s\n", ch4);//abc烫烫烫烫蘟bc //打印完abc之后随机打印,直到遇到\0return 0;
}
3.一维数组的使用
数组通过下标来访问
对于数组使用操作符: [] ,下标引用操作符。它其实就数组访问的操作符
总结:
1. 数组是使用下标来访问的,下标是从0开始。
2. 数组的大小可以通过计算得到。
int arr[10];int sz = sizeof(arr)/sizeof(arr[0]);
int main()
{int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };// 0 1 2 3 4 5 6 7 8 9printf("%d\n", arr[9]);//打印下标为9的元素10//打印数组int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);for (i = 0; i < 10; i++){printf("%d ", arr[i]);}int a = 10;printf("%d\n", sizeof(arr));//40printf("%d\n", sizeof(int[10]));printf("%d\n", sizeof(a));printf("%d\n", sizeof(int));return 0;
}
4、一维数组在内存中的存储
仔细观察输出的结果,我们知道,随着数组下标的增长,元素的地址,也在有规律的递增。由此可以得出结论:数组在内存中是连续存放的。

int main()
{int arr[10] = { 0 };int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);for (i = 0; i < 10; i++){printf("&arr[%d]=%p\n", i,&arr[i]);}return 0;
}
可以看出来:地址是用16进制表示的。0~9和a~f(0~15)
整型数组,首元素地址C0结尾,因为整型占4字节,+4之后就是下一个元素的首元素地址C4,依次类推第三个元素首元素地址为C8..
二、 二维数组的创建和初始化
1.二维数组的创建
//数组创建
int arr[3][4];
char arr[3][5];
double arr[2][4];
2.二维数组的初始化
二维数组的初始化:行可以省略,列不能省略
//数组初始化
int arr[3][4] = {1,2,3,4};
int arr[3][4] = {{1,2},{4,5}};
int arr[][4] = {{2,3},{4,5}};//二维数组如果有初始化,行可以省略,列不能省略
3.二维数组的使用
二维数组的使用也是通过下标的方式。
int main()
{//3行4列//int arr1[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };//int arr1[3][4] = { {1,2},{3,4},{5,6} };//char arr2[5][6];//5行6列//二维数组的初始化:行可以省略,列不能省略//int arr1[][4] = { {1,2},{3,4},{5,6} };int arr1[3][4] = { 1,2,3,4,5,6,7,8,9,10,11,12 };//printf("%d\n", arr1[1][2]);//7//打印二维数组int i = 0;for (i = 0; i < 3; i++){int j = 0;for (j = 0; j < 4; j++){printf("%-2d ", arr1[i][j]);}printf("\n");}return 0;
}
4、二维数组在内存中的存储
二维数组看似多行多列,实际上是连续存储的,本质上还是个一维数组
如果把二维数组的每一行看作一个一维数组,那么每一行的一维数组
也有数组名,arr[0]就是第一行的数组名,arr[1]就是第二行的数组名,以此类推
int main()
{int arr[3][4] = { 0 };int i = 0;int j = 0;for (i = 0; i < 3; i++){for (j = 0; j < 4; j++){printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);}}return 0;
}
三、 数组越界
数组的下标是有范围限制的。
数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。一维数组、二维数组都可能存在越界。C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就 是正确的, 所以程序员写代码时,最好自己做越界的检查
int main()
{int arr[10] = { 0 };int i = 0;for (i = 0; i <= 10; i++)//越界了{printf("%d ", arr[i]);//能运行代码,但在这里arr[i]能看到警告}return 0;
}
可以发现:访问数组内部下标0~9的元素时,都正常打印 0,但是越界打印下标为10的元素,是一个随机值,同时在没有运行的时候,编译器也提示了,在arr[i]下面提示绿色波浪线;
四、数组作为函数参数
往往我们在写代码的时候,会将数组作为参数传个函数,比如:我要实现一个冒泡排序(这里要讲算法 思想)写函数 将一个整形数组排序。在不了解传参真正传递的是什么时候,很容易出现的问题:
错误设计(冒泡排序):
错误原因:误以为传递的参数时整个数组,其实时数组首元素地址
导致了在函数中,计算数组大小时 ,int sz = sizeof(arr)/sizeof(arr[0]);//传参出现问题,sz=1
其实是首元素大小/首元素大小=1。
正确做法:在主函数计算完,再一起传参给函数
//方法1:
#include <stdio.h>
void bubble_sort(int arr[])
{int sz = sizeof(arr)/sizeof(arr[0]);//传参出现问题,sz=1 这样对吗?int i = 0;for(i=0; i<sz-1; i++){int j = 0;for(j=0; j<sz-i-1; j++){if(arr[j] > arr[j+1]){int tmp = arr[j];arr[j] = arr[j+1];arr[j+1] = tmp;}}}
}
int main()
{int arr[] = {3,1,7,5,8,9,0,2,4,6};bubble_sort(arr);//是否可以正常排序?for(i=0; i<sizeof(arr)/sizeof(arr[0]); i++){printf("%d ", arr[i]);}return 0;
}
发现并没有按照我们预期的排序
引出了一个问题:
调试之后可以看到 bubble_sort 函数内部的 sz ,是1。
难道数组作为函数参数的时候,不是把整个数组的传递过去?
数组传参规则:
1. sizeof(数组名),计算整个数组的大小,sizeof内部单独放一个数组名,数组名表示整个数
组。
2. &数组名,取出的是数组的地址。&数组名,数组名表示整个数组。
除此1,2两种情况之外,所有的数组名都表示数组首元素的地址。
1、数组传参传递的是:首元素地址
可以发现:当我们打印数组的地址时,和打印数组第一个元素时,是同一个地址,也就说明了arr的地址就是首元素地址,同时我们对arr地址解引用,得到了第一个元素的值1,更能确信的确是这样
2、数组有时候也代表整个数组

正确设计 - 冒泡排序
正确使用数组传参,完成冒泡排序:先在主函数求出整个数组的大小,传参时再传递数组首元素地址和数组大小
void bubble_sort(int arr[], int sz)//参数接收:数组arr首元素地址,数组元素个数
{//代码同上面函数
}int main()
{int arr[] = {3,1,7,5,8,9,0,2,4,6};int sz = sizeof(arr)/sizeof(arr[0]);bubble_sort(arr, sz);//是否可以正常排序?for(i=0; i<sz; i++){printf("%d ", arr[i]);}return 0;
}
现在运行,正常排序了
相关文章:

初始C语言 - 数组(一维数组、二维数组、数组越界、数组传参)
目录 一、一维数组的创建和初始化 1、数组的创建 2、 数组的初始化 3.一维数组的使用 数组通过下标来访问 总结: 1. 数组是使用下标来访问的,下标是从0开始。 2. 数组的大小可以通过计算得到。 4、一维数组在内存中的存储 二、 二维数组的创建和初始化 1.二…...
人工智能原理复习 | 可分解产生式系统的搜索策略
文章目录 一、前言二、基础知识三、AO* 算法四、博弈树搜索五、总结CSDN 叶庭云:https://yetingyun.blog.csdn.net/ 主要内容: 与 / {/} /或图搜索、AO* 算法、极大极小过程、...

线段树(维护区间信息)
一,定义: 可以在logN时间内实现区间修改,单点修改,区间查询等操作的工具 二,思路(修改无乘法时): 1,建树 通过把区间不断二分建立一颗二叉树 我们以维护一个数组a{1…...

C语言 基于Ncurse库的贪吃蛇游戏项目
为了敲键盘及时响应,需要用到ncurse 测试代码: ncurse1.c /* ncurse1.c */ #include <curses.h> //ncurse的头文件。int main() {char c;int i 0;//ncurse界面的初始化函数。initscr(); for(i0;i<2;i){c getch();printw("\n");//…...

【Java基础】Java语言特性
认识Java java语言的执行过程 编写纯文本文件 .java 经过javac编译器(java complier)编译 .class .class是二进制的字节码 在源文件中定义几个类,就会生成几个 由JVM运行 .class JVM把字节码编译成可以在处理器上运行的高性能的本地代码(native code),…...

python进阶--Numyp库(一)
一、Numpy库介绍 NumPy(Numerical Python)是Python的⼀种开源的数值计算扩展。提供多维数组对象,各种派⽣对象(如掩码数组和矩阵),这种⼯具可⽤来存储和处理⼤型矩阵,⽐Python⾃身的嵌套列表&am…...

CV学习笔记-Inception
CV学习笔记-Inception 目录 文章目录CV学习笔记-Inception目录1. 常见的卷积神经网络2. Inception(1) Inception提出背景(2) Inception module 核心思想3. Inception的历史版本(1) InceptionV1-GoogleNet(2) InceptionV2(3) InceptionV3(4) Inception V44. Inception模型的特点…...

注意力机制笔记——结合沐神和B站老弓up主
B站【大白话浅谈【注意力机制】】 聚类 是针对 样本, 注意力机制是针对样本相关性,来进行计算的 自注意力机制 指的是 query ,key,value都是同一个部分。 可以学到 类似的 短语 ,和 语义特征。如its 指代的对象。 评论区大佬 根据这篇论文《Effective Approaches to…...

建议收藏,轻松搞懂区块链
未来已来,只是不均衡地分布在当下 大家好,我是菜农,欢迎来到我的频道。 本文共 5844字,预计阅读 30 分钟 区块链是近些年来最热门的前沿技术,被认为是未来十几年对金融、物联网、医疗等诸多领域产生最大影响的"…...
php设计一个新春祝福墙
记得十几年前的时候,每到春节,各大网站都会建一个祝福墙,上面挂满网友的新年寄语。这些年随着移动互联网的高速发展,web的新春祝福墙越来越少了。今天,咱们就来考考古,用快速原型法进行设计。原型设计采用M…...

KubeSphere 社区双周报 | OpenFunction 集成 WasmEdge | 2023.02.03-02.16
KubeSphere 社区双周报主要整理展示新增的贡献者名单和证书、新增的讲师证书以及两周内提交过 commit 的贡献者,并对近期重要的 PR 进行解析,同时还包含了线上/线下活动和布道推广等一系列社区动态。 本次双周报涵盖时间为:2023.02.03-2023.…...
数字IC/FPGA 秋招知识点不全面整理
1. 引言 这篇文章的由来 秋招的时候,刚开始复习一些知识点的时候没有什么思路,只是盲目的看相关的书籍和资料,结果是留在脑子中的知识很有限,而且不够系统,在我需要它的时候,并不能很快的回忆起来。 于是就想着把一些典型的知识整理成一个文档,在进行刷题的时候可以比…...
你知道java8是如何排序Map嘛?
在Java中,有多种方法可以对Map进行排序,但是我们将重点介绍Java 8 Stream,这是实现目标的一种非常优雅的方法。 学习一下HashMap的merge()函数 在学习Map排序之前,有必要讲一下HashMap的merge()函数,该函数应用场景就…...
【李忍考研传】一、李忍
“老师,我来回答!” “非常好,我记得你是叫……呃……是李念同学吗?” “不,老师,我叫李忍。” “好,你来回答一下这个问题。” “这题用海明码校验的知识,能检错一位纠错一位&a…...
测牛学堂:软件测试python深入之类和对象的属性和方法总结
类对象和实例对象 类对象就是我们定义的类。 在代码执行的时候,解释器会自动创建类对象。 类对象的作用: 1 使用类对象创建实例对象 2 存储类的一些特性,就是类里面定义的属性 创建对象的过程也称为实例化的对象。所以,类创建的对…...

css实例--新闻页面
实现效果 实现代码 html代码: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" co…...
SpringCloudGateway 动态转发后端服务
API网关的核心功能是统一流量入口,实现路由转发,SpringCloudGateway是API网关开发的技术之一,此外比较流行的还有Kong和ApiSix,这2个都是基于OpenResty技术栈。 简单的路由转发可以通过SpringCloudGateway的配置文件实现…...

使用canvas写一个flappy bird小游戏
简介 canvas 是HTML5 提供的一种新标签,它可以支持 JavaScript 在上面绘画,控制每一个像素,它经常被用来制作小游戏,接下来我将用它来模仿制作一款叫flappy bird的小游戏。flappy bird(中文名:笨鸟先飞&am…...
KVM-2、虚拟化基础
1. 虚拟化概念 什么是虚拟化 **虚拟化是使用所谓虚拟机管理程序从一台物理机上创建若干个虚拟机的过程。**虚拟机的行为和运转方式与物理机一样,但它们会使用物理机的计算资源,如 CPU 、内存和存储。虚拟机管理程序会根据需要将这些计算资源分配给每个虚拟机。 虚拟化有哪…...

设计模式之观察者模式与访问者模式详解和应用
目录1.访问者模式详解1.1 访问者模式的定义1.1.1 访问者模式在生活中的体现1.1.2 访问者模式的适用场景1.2 访问者模式的通用实现1.3 访问者模式的使用案例之KPI考核1.3.1 类图设计1.3.2 代码实现1.4 访问者模式扩展---分派1.4.1 java中静态分派示例代码1.4.2 java中动态分派1.…...
[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?
🧠 智能合约中的数据是如何在区块链中保持一致的? 为什么所有区块链节点都能得出相同结果?合约调用这么复杂,状态真能保持一致吗?本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...

Java面试专项一-准备篇
一、企业简历筛选规则 一般企业的简历筛选流程:首先由HR先筛选一部分简历后,在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如:Boss直聘(招聘方平台) 直接按照条件进行筛选 例如:…...

论文笔记——相干体技术在裂缝预测中的应用研究
目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术:基于互相关的相干体技术(Correlation)第二代相干体技术:基于相似的相干体技术(Semblance)基于多道相似的相干体…...
适应性Java用于现代 API:REST、GraphQL 和事件驱动
在快速发展的软件开发领域,REST、GraphQL 和事件驱动架构等新的 API 标准对于构建可扩展、高效的系统至关重要。Java 在现代 API 方面以其在企业应用中的稳定性而闻名,不断适应这些现代范式的需求。随着不断发展的生态系统,Java 在现代 API 方…...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]
报错信息:libc.so.6: cannot open shared object file: No such file or directory: #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案
引言 在分布式系统的事务处理中,如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议(2PC)通过准备阶段与提交阶段的协调机制,以同步决策模式确保事务原子性。其改进版本三阶段提交协议(3PC…...
二维FDTD算法仿真
二维FDTD算法仿真,并带完全匹配层,输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...

基于开源AI智能名片链动2 + 1模式S2B2C商城小程序的沉浸式体验营销研究
摘要:在消费市场竞争日益激烈的当下,传统体验营销方式存在诸多局限。本文聚焦开源AI智能名片链动2 1模式S2B2C商城小程序,探讨其在沉浸式体验营销中的应用。通过对比传统品鉴、工厂参观等初级体验方式,分析沉浸式体验的优势与价值…...