【嵌入式學習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.pswp.cn/bicheng/74771.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/74771.shtml
英文地址,請注明出處:http://en.pswp.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;點對點直連…