【嵌入式学习2】数组

目录

## 数组概念

## 数组使用

## 数组初始化

## 数组名

## 数组长度

## 数组相关题目

1、找最大值

2、逆置

## 数组和指针

指针加整数的含义

## 指针数组

## 数组名做函数参数

## 函数参数传递数组

1、在函数内部

2. 在函数外部

## 多维数组

使用下标访问

## 字符数组与字符串

## 字符串输入输出

fgets函数

## 字符指针

## 字符串常用库函数

1、strlen

2、strcpy

3、strcat

4、strcmp

## 案例:自定义一个函数my_strlen(),实现的功能和strlen一样


## 数组概念

  • 一种数据结构,用于存储一组具有相同数据类型的数据
  • 每个元素可以通过一个索引(下标)来访问,索引从 0 开始,最大值为数组长度减 1

## 数组使用

#include <stdio.h>int main() {// 定义了一个数组,名字叫a,有10个成员,每个成员都是int类型int a[10]; // a[0]…… a[9],没有a[10]// 没有a这个变量,a是数组的名字,但不是变量名,它是常量a[0] = 0;// ……a[9] = 9;// 数据越界,超出范围,错误// a[10] = 10;  // errfor (int i = 0; i < 10; i++) {a[i] = i; // 给数组赋值}// 遍历数组,并输出每个成员的值for (int i = 0; i < 10; i++) {printf("%d ", a[i]);}printf("\n");return 0;
}

## 数组初始化

	int a1[5] = { 1, 2, 3, 4, 5}; // 定义一个数组,同时初始化所有成员变量int a2[5] = { 1, 2, 3 }; // 初始化前三个成员,后面所有元素都设置为0int a3[5] = { 0 }; // 所有的成员都设置为0// []中不定义元素个数,定义时必须初始化int a4[] = { 1, 2, 3, 4, 5 }; // 定义了一个数组,有5个成员

## 数组名

  • 数组名是一个地址的常量,代表数组中首元素的地址,即arr == &arr[0]

## 数组长度

#include <stdio.h>int main() {// 定义一个数组,同时初始化所有成员变量int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // 数组名是一个地址的常量,代表数组中首元素的地址printf("a = %p\n", a);printf("&a[0] = %p\n", &a[0]);int n = sizeof(a);     // 数组占用内存的大小,10个int类型,10 * 4  = 40int n0 = sizeof(a[0]); // 数组第0个元素占用内存大小,第0个元素为int,4int num = n / n0;      // 元素个数printf("n = %d, n0 = %d, num = %d\n", n, n0, num);return 0;
}

## 数组相关题目

1、找最大值
#include <stdio.h>int main() {// 定义一个数组,同时初始化所有成员变量int a[] = {1, -2, 3, -4, 5, -6, 7, -8, -9, 10};// 假设第0个元素就是最大值int temp = a[0];for (int i = 0; i < sizeof(a) / sizeof(a[0]); i++) {// 如果有元素比临时的最大值大,就交换值if (a[i] > temp) {temp = a[i];}}printf("数组中最大值为:%d\n", temp);return 0;
}
2、逆置
#include <stdio.h>int main() {// 定义一个数组,同时初始化所有成员变量int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int i = 0;  // 首元素下标int j = sizeof(a) / sizeof(a[0]) - 1;   // 尾元素下标int temp;while (i < j) {// 元素交换值temp = a[i];a[i] = a[j];a[j] = temp;// 位置移动i++;j--;}for (i = 0; i < sizeof(a) / sizeof(a[0]); i++) {printf("%d, ", a[i]);}return 0;
}

## 数组和指针

  • 数组名字是数组的首元素地址,但它是一个常量
  • *[]效果一样,都是操作指针所指向的内存
#include <stdio.h>int main() {int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};int i = 0;int n = sizeof(a) / sizeof(a[0]);for (i = 0; i < n; i++) {// * 和 [] 效果一样,都是操作指针所指向的内存// printf("%d, ", a[i]);printf("%d, ", *(a + i)); //a+i参考指针步长}printf("\n");// 定义一个指针变量保存a的地址int *p = a; for (i = 0; i < n; i++) {// printf("%d, ", p[i]);printf("%d, ", *(p + i));}printf("\n");return 0;
}
指针加整数的含义
  • a 是一个指针,假设它指向一个数组的首地址;i 是一个整数。
  • a + i 表示将指针 a 向后移动 i 个单位。这里的“单位”是指指针所指向的数据类型大小。例如:
  • 如果 a 是一个指向 int 类型的指针,那么 a + i 表示将指针 a 向后移动 i * sizeof(int) 字节。
  • 如果 a 是一个指向 char 类型的指针,那么 a + i 表示将指针 a 向后移动 i * sizeof(char) 字节(sizeof(char) 通常为1字节)。

## 指针数组

数组的每一个元素都是指针类型

#include <stdio.h>int main() {// 指针数组int *p[3];int a = 1;int b = 2;int c = 3;// 指针变量赋值p[0] = &a;p[1] = &b;p[2] = &c;for (int i = 0; i < sizeof(p) / sizeof(p[0]); i++) {printf("%d, ", *(*(p + i)));// printf("%d, ", *(p[i]));}printf("\n");return 0;
}
  1. *(p + i):取出数组p中的元素内容
  2. *(*(p + i)):由于每个元素存储的是地址,所以需要对地址解引用

## 数组名做函数参数

#include <stdio.h>// 下面3种写法完全等价
// void print_arr(int a[10], int n)
// void print_arr(int a[], int n)
void print_arr(int *a, int n) {int i = 0;for (i = 0; i < n; i++) {printf("%d, ", a[i]);}printf("\n");
}int main() {int a[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};int n = sizeof(a) / sizeof(a[0]);// 数组名做函数参数print_arr(a, n);return 0;
}

## 函数参数传递数组

引入 <stdint.h> 头文件:这个头文件定义了一系列标准整数类型,这些类型具有明确的大小和符号属性,确保在不同平台和编译器上具有一致的特性。

#include <stdio.h>
#include <stdint.h>// 打印数组, 三种写法皆可
//void print_arr(int arr[5], int size)
//void print_arr(int arr[], int size)
void print_arr(int * arr, int size) {// 对参数arr使用sizeof, 只会得到int指针的大小(固定为8)// [警告] 'sizeof' on array function parameter 'arr' will return size of 'int *' [-Wsizeof-array-argument]printf("数组字节数:%d\n", sizeof(arr));// 数组以参数形式传递时,传递过来的是首元素地址, // 数组的长度信息丢失了,sizeof(arr)得到的是指针的大小,需要将数组的个数size从外部传进来for (int i = 0; i < size; i++) {printf("%d -> %d\n", i, *(arr + i));}}int main() {// 需求:编写一个函数,按格式打印数组int arr[] = {10, 20, 30, 40, 50};// 在声明函数的代码块,通过sizeof(arr)才能得到数组的字节占用数int size = sizeof(arr) / sizeof(arr[0]);print_arr(arr, size);return 0;
}
1、在函数内部
  • 在函数 print_arr 中,参数 arr 是一个指向 int 的指针(int *arr)。因此,sizeof(arr) 实际上是计算指针的大小,而不是数组的大小。
  • 在大多数现代架构(如 x86-64)上,指针的大小通常是 8字节,sizeof(arr) 的结果是 8

2. 在函数外部
  • 在函数外部,arr 是一个数组,数组有 5 个 int 元素
  • 数组大小=5×sizeof(int)=5×4=20字节,sizeof(arr) 的结果是 20

## 多维数组

#include <stdio.h>
#include <stdint.h>// 二维数组,用于保存多组数据
int main() {// 一维数组:元素是数值int stu1[] = {18, 180, 100, 99};int stu2[] = {19, 170,  98, 99};int stu3[] = {20, 160,  90, 92};// 二维数组:元素是一维数组的指针// stus 是一个指针数组,每个元素指向一个一维数组。int * stus_arr[] = {stu1, stu2, stu3};// 第一个[]表示包含了几个一维数组// 第二个[]表示每个一维数组有几个元素int stus[][4] = {{18, 180, 100, 99},{19, 170,  98, 99},{20, 160,  90, 92},};printf("%d\n", stus[1][2]);printf("%d\n", *(stus[1] + 2));return 0;
}
  1. 使用下标访问
  • stus[1][2] 表示访问第 2 行第 3 列的元素。
  • 在 C 语言中,数组下标从 0 开始。
  • 因此,stus[1][2] 对应的值是 98。

2、使用指针访问

  • stus[1] 表示第 2 行的首地址。
  • stus[1] + 2 表示第 2 行首地址向后移动 2 个 int 元素的地址,即第 2 行第 3 列的元素的地址。
  • *(stus[1] + 2) 表示取出该地址所指向的值。
  • 因此,*(stus[1] + 2) 对应的值也是 98。

## 字符数组与字符串

  • C语言中没有字符串,可以通过char的数组来替代
  • 数字0(和字符 '\0' 等价)结尾的char数组就是一个字符串,字符串是一种特殊的char的数组
  • 如果char数组没有以数字0结尾,就不是一个字符串,只是普通字符数组
#include <stdio.h>int main() {char c1[] = {'c', ' ', 'p', 'r', 'o', 'g'}; // 普通字符数组printf("c1 = %s\n", c1);                    // 有可能乱码,因为没有'\0'结束符// 以'\0'('\0'就是数字0)结尾的字符数组是字符串char c2[] = {'c', ' ', 'p', 'r', 'o', 'g', '\0'};printf("c2 = %s\n", c2);// 字符串处理以'\0'(数字0)作为结束符,后面的'h', 'l', 'l', 'e', 'o'不会输出char c3[] = {'c', ' ', 'p', 'r', 'o', 'g', '\0', 'h', 'l', 'l', 'e', 'o', '\0'};printf("c3 = %s\n", c3);// 使用字符串初始化,编译器自动在后面补0,常用char c4[] = "c prog";printf("c4 = %s\n", c4);return 0;
}

## 字符串输入输出

#include <stdio.h>int main()
{char str[100];printf("input string1: ");// scanf("%s",str) 默认以空格分隔// 可以输入空格gets(str);printf("output: %s\n", str);return 0;
}

注意:gets函数存在容易溢出缓冲区的问题,可使用fgets函数

问题:
char buffer[10];
gets(buffer); // 如果用户输入的字符串超过9个字符,就会导致缓冲区溢出
fgets函数
char buffer[10];
fgets(buffer, sizeof(buffer), stdin); // 安全地读取最多9个字符
  • fgets 会从输入流中读取最多 size - 1 个字符(包括换行符),并在末尾添加一个空字符(\0)作为字符串的终止符。

## 字符指针

  • 字符指针可直接赋值为字符串,保存的实际上是字符串的首地址,字符串指针所指向的内存不能修改,指针变量本身可以修改
#include <stdio.h>int main() {char *p = "hello";  // 和 const char *p = 'hello' 等价,有没有const都一样// 指针变量所指向的内存不能修改// *p = 'a';    // errprintf("p = %s\n", p);// 指针变量可以修改p = "world";printf("p = %s\n", p);return 0;
}

## 字符串常用库函数

1、strlen
#include <string.h>
size_t strlen(const char *s);
功能:计算指定指定字符串s的长度,不包含字符串结束符‘\0’
参数:s:字符串首地址
返回值:字符串s的长度,size_t为unsigned int类型,不同平台会不一样
2、strcpy
#include <string.h>
char *strcpy(char *dest, const char *src);
功能:把src所指向的字符串复制到dest所指向的空间中,'\0'也会拷贝过去
参数:dest:目的字符串首地址,如果参数dest所指的内存空间不够大,可能会造成缓冲溢出的错误情况src:源字符首地址
返回值:成功:返回dest字符串的首地址失败:NULL#include <stdio.h>
#include <string.h>int main() {char dest[20] = "123456789";char src[] = "hello world";strcpy(dest, src);printf("%s\n", dest);return 0;
}
3、strcat
#include <string.h>
char *strcat(char *dest, const char *src);
功能:将src字符串连接到dest的尾部,‘\0’也会追加过去
参数:dest:目的字符串首地址src:源字符首地址
返回值:成功:返回dest字符串的首地址失败:NULL#include <stdio.h>
#include <string.h>int main() {char str[20] = "123";char *src = "hello world";strcat(str, src);printf("%s\n", str); //结果123hello worldreturn 0;
}
4、strcmp
#include <string.h>
int strcmp(const char *s1, const char *s2);
功能:比较 s1 和 s2 的大小,比较的是字符ASCII码大小。
参数:s1:字符串1首地址s2:字符串2首地址
返回值:相等:0大于:>0小于:<0

## 案例:自定义一个函数my_strlen(),实现的功能和strlen一样

#include <stdio.h>// 函数定义
int my_strlen(char * temp) {// 定义一个累加个数的变量,初始值为0int i = 0;// 循环遍历每一个字符,如果是'\0'跳出循环while (temp[i] != '\0') {// 下标累加i++;}return i;
}int main() {char *p = "hello";// 函数调用int n = my_strlen(p);printf("n = %d\n", n);return 0;
}

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

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

相关文章

C++中的判断与循环

一.if判断语句 1.程序中的判断&#xff1a; if (要执行的判断&#xff0c;最后的返回值要是bool型的数据) {如果为真&#xff0c;要执行的代码段; } #include"iostream" using namespace std;int main() {int ans;cin >> ans;if (ans > 1000) {cout <…

前端开发中生成网站的favicon.ico文件的软件推荐及使用方法

日常网站开发中&#xff0c;我们经常需要生成网站的favicon.ico文件&#xff0c;今天我在这里来推荐几个编辑.ico(也可将图片格式转化为.ico)图片&#xff0c;而且免费的那软件&#xff1a; GIMP&#xff1a;一个功能强大的开源图像编辑软件&#xff0c;支持多种文件格式&#…

浅谈WebSocket-FLV

FLV是一种视频数据封装格式&#xff0c;这种封装被标准通信协议HTTP-FLV和RTMP协议应用。 而WebSocket-FLV是一种非标的FLV封装数据从后端发送到前端的一种方式。 在WebSocket的url请求中&#xff0c;包含了需要请求设备的视频相关信息&#xff0c;在视频数据到达时&#xff0c…

基于ADMM无穷范数检测算法的MIMO通信系统信号检测MATLAB仿真,对比ML,MMSE,ZF以及LAMA

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 ADMM算法 4.2 最大似然ML检测算法 4.3 最小均方误差&#xff08;MMSE&#xff09;检测算法 4.4 迫零&#xff08;ZF&#xff09;检测算法 4.5 OCD_MMSE 检测算法 4.6 LAMA检测算法 …

cocos creator 笔记-路边花草

版本&#xff1a;3.8.5 实现目标&#xff1a;给3d道路生成路边景观花草 在场景下创建一个节点&#xff0c;我这里种植两种花草模型&#xff0c;兰花和菊花&#xff0c;所以分别在节点下另创建两个节点&#xff0c;为了静态合批。 1.将花草模型分别拖入场景中&#xff0c;制作…

R语言——循环

参考资料&#xff1a;学习R 在R中有三种循环&#xff1a;repeat、while和for。虽然向量化意味着我们可能并不需要大量使用它们&#xff0c;但在需要重复执行代码时&#xff0c;它们是非常有用的。 1、重复循环 R中最容易掌握的循环是repeat。它所做的事情就是反复地执行代码&a…

springboot使用阿里限流框架-sentinel

当前项目源码 控制台下载 启动bin中的看板服务&#xff1a;账号密码:sentinel/sentinel 官方文档地址 项目引入依赖 <!-- sentinel注解支持 --> <dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-annotation-aspectj<…

CSS3学习教程,从入门到精通,CSS3 元素的浮动与定位语法知识点及案例代码(17)

CSS3 元素的浮动与定位语法知识点及案例代码 一、CSS3 浮动&#xff08;float&#xff09; 知识点 1. **定义** &#xff1a;浮动使元素向左或向右移动&#xff0c;直到它的外边缘碰到包含框或另一个浮动元素的边框为止。浮动主要用于布局&#xff0c;如实现图文绕排等效果。…

数据结构:汉诺塔问题的递归求解和分析

递归方法求解该类问题&#xff0c;是一种简单的思维方法&#xff0c;通常比使用迭代方法更简单。但是&#xff0c;递归方法也有劣势。此处以典型的汉诺塔问题&#xff08;Tower of Hanoi&#xff09;为例给予说明。 汉诺塔是根据一个传说形成的数学问题&#xff0c;最早是由法国…

3.27学习总结 算法题

自己用c语言做的&#xff0c;不尽如意 后面看了题解&#xff0c;用的是c&#xff0c;其中string 变量和字符串拼接感觉比c方便好多&#xff0c;可以用更少的代码实现更好的效果&#xff0c;打算之后去学习c&#xff0c;用c写算法。 递归&#xff0c;不断输入字符&#xff0c;…

vue 图片放大到全局

背景&#xff1a; 在vue项目中&#xff0c;el-image组件图片组件用于展示图片&#xff0c;组件自带的属性preview-teleported&#xff0c;设置为true可以控制图片放大到全局 实现效果&#xff1a; 核心代码&#xff1a; //图片地址&#xff1a;BASEUrl /file/ item.file //这…

【商城实战(75)】数据分析指标体系搭建:从0到1的技术指南

【商城实战】专栏重磅来袭&#xff01;这是一份专为开发者与电商从业者打造的超详细指南。从项目基础搭建&#xff0c;运用 uniapp、Element Plus、SpringBoot 搭建商城框架&#xff0c;到用户、商品、订单等核心模块开发&#xff0c;再到性能优化、安全加固、多端适配&#xf…

seatunnel配置mysql2hive

SeaTunnel安装教程 # 执行流程 # 下载&#xff0c;解压 # https://mirrors.aliyun.com/apache/seatunnel/2.3.8/?spma2c6h.25603864.0.0.2e2d3f665eBj1E # https://blog.csdn.net/taogumo/article/details/143608532 tar -zxvf apache-seatunnel-2.3.8-bin.tar.gz -C /opt/mo…

SSH项目负载均衡中的Session一致性解决方案‌

SSH项目负载均衡中的Session一致性解决方案‌ 1. 粘性会话&#xff08;Session Sticky&#xff09;‌2. Session复制&#xff08;集群同步&#xff09;‌3. 集中式Session存储‌4. 客户端存储&#xff08;Cookie加密&#xff09;‌方案选型建议‌注意事项‌ 1. 粘性会话&#x…

MySQL 表连接(内连接与外连接)

&#x1f3dd;️专栏&#xff1a;Mysql_猫咪-9527的博客-CSDN博客 &#x1f305;主页&#xff1a;猫咪-9527-CSDN博客 “欲穷千里目&#xff0c;更上一层楼。会当凌绝顶&#xff0c;一览众山小。” 目录 1、表连接的核心概念 1.1 为什么需要表连接&#xff1f; 2、内连接&a…

解锁Spring Boot异步编程:让你的应用“飞“起来!

引言&#xff1a;从点餐说起 &#x1f354; 想象你在快餐店点餐&#xff1a; 同步模式&#xff1a;排队等餐&#xff0c;队伍越来越长&#xff08;就像卡死的服务器&#xff09;异步模式&#xff1a;拿号后去旁边坐着等&#xff08;服务员喊号通知你&#xff09; 今天我们就…

做一个有天有地的css及html画的旋转阴阳鱼

<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>天地阴阳</title><style>/* 重置默认样…

ngx_http_core_main_conf_t

定义在 src\http\ngx_http_core_module.h typedef struct {ngx_array_t servers; /* ngx_http_core_srv_conf_t */ngx_http_phase_engine_t phase_engine;ngx_hash_t headers_in_hash;ngx_hash_t variables_hash;…

计算机二级(C语言)考试高频考点总汇(二)—— 控制流、函数、数组和指针

目录 六、控制流 七、函数 八、数组和指针 六、控制流 76. if 语句可以&#xff08;嵌套&#xff09;&#xff0c; if 语句可以嵌套在另一个 if 语句内部&#xff0c;形成&#xff08;嵌套的条件判断结构&#xff09;&#xff0c;用于处理更复杂的条件判断逻辑。 77. els…

WebRTC协议全面教程:原理、应用与优化指南

一、WebRTC协议概述 **WebRTC&#xff08;Web Real-Time Communication&#xff09;**是一种开源的实时通信协议&#xff0c;支持浏览器和移动应用直接进行音频、视频及数据传输&#xff0c;无需插件或第三方软件。其核心特性包括&#xff1a; P2P传输&#xff1a;点对点直连…