当前位置: 首页 > news >正文

品牌设计公司名字/整站优化的公司

品牌设计公司名字,整站优化的公司,学做包子馒头的网站,wordpress数据查询网站目录 1. 一维数组的创建和初始化 1.1 数组的创建 1.2 数组的初始化 1.3 一维数组的使用 1.4 一维数组在内存中的存储 2. 二维数组的创建和初始化 2.1 二维数组的创建 2.2 二维数组的初始化 2.3 二维数组的使用 2.4 二维数组在内存中的存储 3. 数组越界 4. 数组作为函数参数 4.1…

目录

1. 一维数组的创建和初始化

1.1 数组的创建

1.2 数组的初始化

1.3 一维数组的使用

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

2. 二维数组的创建和初始化

2.1 二维数组的创建

2.2 二维数组的初始化

2.3 二维数组的使用

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

3. 数组越界

4. 数组作为函数参数

4.1 冒泡排序函数的设计

4.1.1 关于冒泡排序函数的错误设计

4.1.2 关于冒泡排序函数的正确设计

4.2 数组名是什么?

对于二维数组的数组名


我们原来要存放一个整数, 就会:

int a = 1;
int b = 2;
int c = 3;

那么如果要存放1~10, 或者要存放1~100呢? 如果创建10或100个变量就不方便了, 于是就有了数组的概念.

什么是数组? 数组是一组相同类型元素的集合.

那么C语言的数组形式是什么呢, 我们一起来看.

1. 一维数组的创建和初始化

1.1 数组的创建

数组的创建方式:

type_t arr_name [const_n];
// type_t 是数组的元素类型
// arr_name 是数组的数组名
// const_n 是一个常量表达式, 用来指定数组的大小

数组创建的实例:

int arr[10];
char ch[5];
double data1[20];
double data2[15+5];

注: 数组创建,在C99标准之前,[]中要给一个常量或者常量表达式才可以,不能使用变量。在C99之后,数组的大小可以是变量,这是为了支持变长数组。

//下面的代码只能在支持C99标准的编译器上编译
int n = 10;
scanf("%d", &n);
int arr2[n];//这种数组是不能初始化

1.2 数组的初始化

数组的初始化是指,在创建数组的同时给数组的内容一些合理初始值(初始化).

数组在创建的时候如果想不指定数组的确定的大小就得初始化。数组的元素个数根据初始化的内容来确定。

//不完全初始化,剩余的元素默认初始化为0
int arr[10] = { 1,2,3 };
int arr1[10] = { 1,2,3,4,5,6,7,8,9,0 };
int arr2[] = { 1,2,3 };

但是对于下面的代码要区分,内存中如何分配。

char ch1[10] = { 'a', 'b', 'c' };
//a b c 0 0 0 0 0 0 0
char ch2[10] = "abc";
//a b c \0 0 0 0 0 0 0
char ch3[] = { 'a', 'b', 'c' };
char ch4[] = "abc";

1.3 一维数组的使用

对于数组的使用我们之前介绍了一个操作符: [],下标引用操作符。它其实就数组访问的操作符.

int arr[] = { 1,2,3,4,5,6,7,8,9,10 }; 
//            0 1                9

当我们去访问上面这个数组的时候, 需要知道它在内存中的情况.

这段代码对应的是在内存中的栈区找了一块连续的空间, 在里面放了1~10.

那么我们可以通过下标引用操作符+下标编号来访问数组中的元素.

printf("%d\n", arr[4]);

如果要打印数组的每个元素:

int main()
{int arr[] = { 1,2,3,4,5,6,7,8,9,10 };int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);//顺序打印for (i = 0; i < sz; i++){printf("%d ", arr[i]);}//逆序打印for (i = sz - 1; i >= 0; i--){printf("%d ", arr[i]);}return 0;
}
总结:
1. 数组是使用下标来访问的,下标是从0开始
2. 数组的大小可以通过计算得到。

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

在上面的代码中加入:

    for (i = 0; i < sz; i++){printf("&arr[%d] = %p\n", i, &arr[i]);}

可以看到数组的,每个元素的地址:

观察输出的结果,可以知道,随着数组下标的增长,元素的地址,也在有规律的递增.

由此我们得出: 数组在内存中是连续存放的.

那么我们同样也是可以通过调试在内存窗口中看到数组arr在内存中的分布情况.

2. 二维数组的创建和初始化

二维数组相较于一维数组能够存放更多的数据. 它存在的原因就是因为相同的数据是可能会出现很多组. 像这种多组整数需要存储的话就可以考虑二维数组.

2.1 二维数组的创建

int arr[3][4];    // 第一个[]表示行, 第二个[]表示列. 3行4列.
char arr[3][5];
double arr[2][4];
可以看到在数组名后有两个 [], 对于第一行它表示的是三行四列的元素, 就像一个表格一样.
我们知道一维数组是一行, 而二维数组是有多行. 其实这就是一个概念.
比如说要存放下面这几组数据:
1 2 3 4
2 3 4 5
3 4 5 6

那么我们就可以创建如上文第一行代码的那样一个数组.

2.2 二维数组的初始化

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}}; 
int arr3[][4] = { 1,2,3,4,5,6};//二维数组如果有初始化,行可以省略,列不能省略

可以看到, arr1第一行为1234, 第二行为2345, 第三行为3456. 因为我们前面已经限定了一行能放四个元素, 所以当第一行放了四个元素之后紧接着后面的初始化内容又找了四个给第二行, 再找四个给到第三行.
所以能看到如上图所示的现象.

那么如果初始化的数字不够数的时候, 会在后面初始化成0, 也如上图arr2和arr3所示.

2.3 二维数组的使用

二维数组的使用也是通过下标的方式.

#include <stdio.h>int main()
{int arr[3][4] = { 1,2,3,4,2,3,4,5,3,4,5,6 };int i = 0;for (i = 0; i < 3; i++){int j = 0;for (j = 0; j < 4; j++){printf("%d ", arr[i][j]);}printf("\n");}return 0;
}

运行结果:

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

前面在我们假想中的二维数组是多行多列的一个存在, 但是实际上在内存中并不是使用行列这种样子的存储方式, 而是连续的存储.

我们来进行验证, 打印二维数组每个元素的地址:

#include <stdio.h>int main()
{int arr[3][4] = { 1,2,3,4,2,3,4,5,3,4,5,6 };int i = 0;for (i = 0; i < 3; i++){int j = 0;for (j = 0; j < 4; j++){printf("&arr[%d][%d] = %p\n", i, j, &arr[i][j]);}}return 0;
}

输出结果:

通过地址的变化可以观察出: 二维数组在内存中也是连续存放的.

于是, 我们可以进一步这样理解二维数组.

int arr[3][4];
理解为从第一个元素开始向后的连续12个空间, 看成是一个连续的一维数组, 有12个元素.
其实最终, 该代码与
int arr2[12];
在内存中的布局是一样的.
可以把二维数组理解为: 一维数组的数组.

3. 数组越界

数组的下标是有范围限制的。

数组的下规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是n-1。

所以数组的下标如果小于0,或者大于n-1,就是数组越界访问了,超出了数组合法空间的访问。

C语言本身是不做数组下标的越界检查,编译器也不一定报错,但是编译器不报错,并不意味着程序就是正确的。

所以程序员写代码时,最好自己做越界的检查。

二维数组的行和列也可能存在越界。

4. 数组作为函数参数

往往我们在写代码的时候,会将数组作为参数传个函数,比如: 我要实现一个冒泡排序函数将一个整形数组排序.

冒泡排序的核心思想: 两个相邻的元素进行比较

代码思路:

4.1 冒泡排序函数的设计

4.1.1 关于冒泡排序函数的错误设计

int main()
{//数组//把数组的数据排成升序int arr[] = { 9,8,7,6,5,4,3,2,1,0 };//0 1 2 3 4 5 6 7 8 9int sz = sizeof(arr) / sizeof(arr[0]);//冒泡排序的算法,对数组进行排序bubble_sort(arr);int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}
void bubble_sort(int arr[])
{//趟数int sz = sizeof(arr) / sizeof(arr[0]);int i = 0;for (i = 0; i < sz - 1; i++){//一趟冒泡排序int j = 0;for (j = 0; j < sz - 1 - i; j++){if (arr[j] > arr[j + 1]){//交换int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}
}

执行上述代码之后, 会出问题, 并不能正确的将数据进行排序.

我们进行调试:

在调试到bubble_sort()中发现sz变成了1, 但是我们期望是10, 此时往下1-1=0, 并没有进行任何的对数据排序就退出了这个函数, 所以当整个程序执行完会发现并没有将数据进行排序就输出.

这是函数程序的编写中非常常见的错误.

4.1.2 关于冒泡排序函数的正确设计

//形参是数组的形式
void bubble_sort(int arr[],int sz)
{//趟数int i = 0;for (i = 0; i < sz - 1; i++){//一趟冒泡排序int j = 0;for (j = 0; j < sz - 1 - i; j++){if (arr[j] > arr[j + 1]){//交换int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}
}int main()
{//数组//把数组的数据排成升序int arr[] = { 9,8,7,6,5,4,3,2,1,0 };//0 1 2 3 4 5 6 7 8 9int sz = sizeof(arr) / sizeof(arr[0]);//冒泡排序的算法,对数组进行排序bubble_sort(arr, sz);int i = 0;for (i = 0; i < sz; i++){printf("%d ", arr[i]);}return 0;
}
//形参是指针的形式
void bubble_sort(int* arr,int sz)
{//趟数int i = 0;for (i = 0; i < sz-1; i++){//一趟冒泡排序int j = 0;for (j=0; j<sz-1-i; j++){if (arr[j] > arr[j + 1]){//交换int tmp = arr[j];arr[j] = arr[j + 1];arr[j + 1] = tmp;}}}
}

4.2 数组名是什么?

前面提到, 数组名是数组首元素的地址, 这个说法虽然对, 但是其实并不完全对, 有两个例外.

1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节

2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址

int main()
{int arr[10] = {0};printf("%p\n", arr);//arr就是首元素的地址printf("%p\n", arr+1);printf("----------------------\n");printf("%p\n", &arr[0]);//首元素的地址printf("%p\n", &arr[0]+1);printf("----------------------\n");printf("%p\n", &arr);//数组 的地址printf("%p\n", &arr+1);//int n = sizeof(arr);//40//printf("%d\n", n);return 0;
}

执行结果:


对于二维数组的数组名

#include <stdio.h>int main()
{int arr[3][4] = {0};printf("%d\n", sizeof(arr) / sizeof(arr[0]));//计算行printf("%d\n", sizeof(arr[0]) / sizeof(arr[0][0]));//计算列int sz = sizeof(arr);printf("%d\n", sz);    //48printf("%p\n", arr);//二维数组的数组名也表示数组首元素的地址(第一行的地址)printf("%p\n", arr+1);//第二行return 0;
}

相关文章:

C语言 - 数组

目录 1. 一维数组的创建和初始化 1.1 数组的创建 1.2 数组的初始化 1.3 一维数组的使用 1.4 一维数组在内存中的存储 2. 二维数组的创建和初始化 2.1 二维数组的创建 2.2 二维数组的初始化 2.3 二维数组的使用 2.4 二维数组在内存中的存储 3. 数组越界 4. 数组作为函数参数 4.1…...

Vue 中的插槽(Slot),有什么用,不同插槽的区别?

Vue 中的插槽&#xff08;Slot案例详解&#xff09; 是一种非常有用的功能&#xff0c;用于组件之间的内容分发和复用。以下是关于插槽的一些重要概念&#xff1a; 插槽的作用: 插槽允许你将组件的内容分发到其子组件中&#xff0c;以实现灵活的组件复用和自定义布局。通过插槽…...

Linux登录自动执行脚本

一、所有用户每次登录时自动执行。 1、在/etc/profile文件末尾添加。 将启动命令添加到/etc/profile文件末尾。 2、在/etc/profile.d/目录下添加sh脚本。 在/etc/profile.d/目录下新建sh脚本&#xff0c;设置每次登录自动执行脚本。有用户登录时&#xff0c;/etc/profile会遍…...

架构方法、模型、范式、治理

从架构方法、模型、范式、治理等四个方面介绍架构的概念和方法论、典型业务场景下的架构范式、不同架构的治理特点这3个方面的内容...

Linux 安全 - 内核提权

文章目录 前言一、简介1.1 prepare_creds1.2 commit_creds 二、demo参考资料 前言 在这篇文章&#xff1a;Linux 安全 - Credentials 介绍了 Task Credentials 相关的知识点&#xff0c;接下来给出一个内核编程提权的例程。 一、简介 内核模块提权主要借助于 prepare_creds …...

数字三角形加强版题解(组合计数+快速幂+逆元)

Description 一个无限行的数字三角形&#xff0c;第 i 行有 i 个数。第一行的第一个数是 1 &#xff0c;其他的数满足如下关系&#xff1a;如果用 F[i][j] 表示第 i 行的第 j 个数&#xff0c;那么 F[i][j]A∗F[i−1][j]B∗F[i−1][j−1] &#xff08;不合法的下标的数为 0 &a…...

MySQL:主从复制-基础复制(6)

环境 主服务器 192.168.254.1 从服务器&#xff08;1&#xff09;192.168.254.2 从服务器&#xff08;2&#xff09;192.168.253.3 我在主服务器上执行的操作会同步至从服务器 主服务器 yum -y install ntp 我们去配置ntp是需要让从服务器和我们主服务器时间同步 sed -i /…...

盒子模型的基础

盒子模型 边框&#xff08;border&#xff09; border可以设置元素的边框&#xff0c;边框分成三部分&#xff0c;边框的&#xff08;粗细&#xff09;边框的样式&#xff0c;边框的颜色 <style>div {width: 100px;height: 100px;border-width: 200;border-style: 边框…...

Go复合类型之数组类型

Go复合类型之数组 文章目录 Go复合类型之数组一、数组(Array)介绍1.1 基本介绍1.2 数组的特点 二、数组的声明与初始化2.1 数组声明2.2 常见的数据类型声明方法2.3 数组的初始化方式一&#xff1a;使用初始值列表初始化数组方法二&#xff1a;根据初始值个数自动推断数组长度方…...

rust闭包

一、闭包是什么 &#xff08;一&#xff09;闭包是什么 我们先来看看javascript中的闭包。 在函数外部无法读取函数内的局部变量。但是我们有时候需要得到函数内的局部变量&#xff0c;那么如何从外部读取局部变量&#xff1f;那就是在函数的内部&#xff0c;再定义一个函数。…...

通过位运算,实现单字段标识多个状态位

可能经常有如下这种需求: 需要一张表,来记录学员课程的通过与否. 课程数量不确定,往往很多,且会有变动,随时可能新增一门课. 这种情况下,在设计表结构时,一门课对应一个字段,就有些不合适, 因为不知道课程的具体数量,也无法应对后期课程的增加. 考虑只用一个状态标志位,利用位运…...

ALSA pcm接口的概念解释

PCM(数字音频)接口 PCM缩写: Pulse Code Modulation脉冲调制编码,我们理解为通过一定连续时间周期产生数字音频并带有音量样本的处理过程. 模拟信号被记录通过模拟到数字转换器,数字值(也就是某个特定时刻的音量值)获得来自ADC可以进一步处理,接下的图片展示的是个sine wavefor…...

logging的基本使用教程

logging的基本使用教程 一、简介&#xff1a; logging模块是Python的标准库&#xff0c;用于记录应用程序运行时的日志信息。使用logging模块可以帮助您在开发过程中调试代码、追踪问题和监控应用程序的运行状况。 二、使用教程 1、logging模块的基本使用方法&#xff1a; …...

ds套dp——考虑位置转移or值域转移:CF1762F

https://www.luogu.com.cn/problem/CF1762F 分析性质&#xff0c;就是我们选的数要么递增&#xff0c;要么递减&#xff08;非严格&#xff09;然后很明细是ds套dp&#xff0c; f i f_i fi​ 表示以 i i i 开头的答案然后考虑如何转移&#xff08;ds套dp难点反而在转移而不是…...

stm32的GPIO寄存器操作以及GPIO外部中断,串口中断

一、学习参考资料 &#xff08;1&#xff09;正点原子的寄存器源码。 &#xff08;2&#xff09;STM32F103最小系统板开发指南-寄存器版本_V1.1&#xff08;正点&#xff09; &#xff08;3&#xff09;STM32F103最小系统板开发指南-库函数版本_V1.1&#xff08;正点&a…...

生成对抗网络入门案例

前言 生成对抗网络&#xff08;Generative Adversarial Networks&#xff0c;简称GANs&#xff09;是一种用于生成新样本的机器学习模型。它由两个主要组件组成&#xff1a;生成器&#xff08;Generator&#xff09;和判别器&#xff08;Discriminator&#xff09;。生成器尝试…...

多头注意力机制

1、什么是多头注意力机制 从多头注意力的结构图中&#xff0c;貌似这个所谓的多个头就是指多组线性变换&#xff0c;但是并不是&#xff0c;只使用了一组线性变换层&#xff0c;即三个变换张量对 Q、K、V 分别进行线性变换&#xff0c;这些变化不会改变原有张量的尺寸&#xf…...

Qt + FFmpeg 搭建 Windows 开发环境

Qt FFmpeg 搭建 Windows 开发环境 Qt FFmpeg 搭建 Windows 开发环境安装 Qt Creator下载 FFmpeg 编译包测试 Qt FFmpeg踩坑解决方法1&#xff1a;换一个 FFmpeg 库解决方法2&#xff1a;把项目改成 64 位 后记 官方博客&#xff1a;https://www.yafeilinux.com/ Qt开源社区…...

[网鼎杯 2020 白虎组]PicDown python反弹shell proc/self目录的信息

[网鼎杯 2020 白虎组]PicDown - 知乎 这里确实完全不会 第一次遇到一个只有文件读取思路的题目 这里也确实说明还是要学学一些其他的东西了 首先打开环境 只存在一个框框 我们通过 目录扫描 抓包 注入 发现没有用 我们测试能不能任意文件读取 ?url../../../../etc/passwd …...

SDL2绘制ffmpeg解析的mp4文件

文章目录 1.FFMPEG利用命令行将mp4转yuv4202.ffmpeg将mp4解析为yuv数据2.1 核心api: 3.SDL2进行yuv绘制到屏幕3.1 核心api 4.完整代码5.效果展示6.SDL2事件响应补充6.1 处理方式-016.2 处理方式-02 本项目采用生产者消费者模型&#xff0c;生产者线程&#xff1a;使用ffmpeg将m…...

决策树C4.5算法的技术深度剖析、实战解读

目录 一、简介决策树&#xff08;Decision Tree&#xff09;例子&#xff1a; 信息熵&#xff08;Information Entropy&#xff09;与信息增益&#xff08;Information Gain&#xff09;例子&#xff1a; 信息增益比&#xff08;Gain Ratio&#xff09;例子&#xff1a; 二、算…...

LLMs Python解释器程序辅助语言模型(PAL)Program-aided language models (PAL)

正如您在本课程早期看到的&#xff0c;LLM执行算术和其他数学运算的能力是有限的。虽然您可以尝试使用链式思维提示来克服这一问题&#xff0c;但它只能帮助您走得更远。即使模型正确地通过了问题的推理&#xff0c;对于较大的数字或复杂的运算&#xff0c;它仍可能在个别数学操…...

【12】c++设计模式——>单例模式练习(任务队列)

属性&#xff1a; &#xff08;1&#xff09;存储任务的容器&#xff0c;这个容器可以选择使用STL中的队列&#xff08;queue) &#xff08;2&#xff09;互斥锁&#xff0c;多线程访问的时候用于保护任务队列中的数据 方法&#xff1a;主要是对任务队列中的任务进行操作 &…...

Python之函数、模块、包库

函数、模块、包库基础概念和作用 A、函数 减少代码重复 将复杂问题代码分解成简单模块 提高代码可读性 复用老代码 """ 函数 """# 定义一个函数 def my_fuvtion():# 函数执行部分print(这是一个函数)# 定义带有参数的函数 def say_hello(n…...

SQL创建与删除索引

索引创建、删除与使用&#xff1a; 1.1 create方式创建索引&#xff1a;CREATE [UNIQUE – 唯一索引 | FULLTEXT – 全文索引 ] INDEX index_name ON table_name – 不指定唯一或全文时默认普通索引 (column1[(length) [DESC|ASC]] [,column2,…]) – 可以对多列建立组合索引 …...

网络协议--链路层

2.1 引言 从图1-4中可以看出&#xff0c;在TCP/IP协议族中&#xff0c;链路层主要有三个目的&#xff1a; &#xff08;1&#xff09;为IP模块发送和接收IP数据报&#xff1b; &#xff08;2&#xff09;为ARP模块发送ARP请求和接收ARP应答&#xff1b; &#xff08;3&#xf…...

HDLbits: Count clock

目前写过最长的verilog代码&#xff0c;用了将近三个小时&#xff0c;编写12h显示的时钟&#xff0c;改来改去&#xff0c;估计只有我自己看得懂&#xff08;吐血&#xff09; module top_module(input clk,input reset,input ena,output pm,output [7:0] hh,output [7:0] mm,…...

【1day】用友移动管理系统任意文件上传漏洞学习

注:该文章来自作者日常学习笔记,请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与作者无关。 目录 一、漏洞描述 二、影响版本 三、资产测绘 四、漏洞复现...

【c++】向webrtc学习容器操作

std::map的key为std::pair 时的查找 std::map<RemoteAndLocalNetworkId, size_t> in_flight_bytes_RTC_GUARDED_BY(&lock_);private:using RemoteAndLocalNetworkId = std::pair<uint16_t, uint16_t...

SpringBoot+Vue3外卖项目构思

SpringBoot的学习&#xff1a; SpringBoot的学习_明里灰的博客-CSDN博客 实现功能 前台 用户注册&#xff0c;邮箱登录&#xff0c;地址管理&#xff0c;历史订单&#xff0c;菜品规格&#xff0c;购物车&#xff0c;下单&#xff0c;菜品浏览&#xff0c;评价&#xff0c;…...