C語言-數組指針和指針數組

指針

數組指針與指針數組

數組指針
定義

概念:數組指針是指向數組的指針,本質上還是指針

特點:

①先有數組,后有指針

②它指向的是一個完整的數組

一維數組指針

語法:

?數據類型 (*指針變量名)[容量];

案例:

?/*int arr[] = {11,22,33,44,55};?int *p = arr;p++;*/??/*************************************************************************> File Name: ?  demo01.c> Author: ? ? ? 趙生鑫> Description: ?> Created Time: 2025年03月20日 星期四 09時48分24秒************************************************************************/?#include <stdio.h>?/***數組指針:指向數組的指針(這里指向整個數組,不是數組的某個元素)** */?int main(int argc,char *argv[]){//一維數組指針//先有數組,再有指針//指針不能獨立存在,必須依賴與現有的常量或者變量空間int arr[] = {100,200,300};?//獲取數組大小int len = sizeof(arr) / sizeof(arr[0]);?//指針變量指向數組元素:此時指針指向的時數組中的第一個元素,此時指針存儲的值是首元素的地址值//數組指針指向整個數組:此時指針指向的是整個數組,此時指針存儲的值是首元素的地址值?//定義一個數組指針int (*p)[3] = &arr;//arr默認指向首元素,&arr指向整個數組?//p++  此時不能p++,否則會越界printf("%p,%p,%p\n",p,&arr,arr);//輸出3個地址相等?//如何訪問數組指針printf("%d\n",(*p)[2]);?//遍歷數組指針for ( int i = 0;i < len ;i++){printf("%-6d",(*p)[i]);//數組指針本質是指針,所以我們需要添加()提升指針優先級(默認數組優先)}printf("\n");return 0;}

我們之前所學的是指向數組元素的指針,本質上是指針變量;現在我們學的是指向數組的指針,叫做數組指針

二維數組指針

語法:

?數據類型 (*指針變量名)[行容量][列容量];

案例:

  • 寫法1

    ?/*************************************************************************> File Name: ?  demo02.c> Author: ? ? ? 趙生鑫> Description: ?> Created Time: 2025年03月20日 星期四 10時17分55秒************************************************************************/?#include <stdio.h>?int main(int argc,char *argv[]){int arr[][3] = {11,22,33,44,55,66,77,88,99};?//定義一個數組指針指向二維數組arr//int (*p)[][3] = &arr; ? 數組指針指向二維數組,不推薦int (*p)[3] = arr;//數組指針指向二維數組首行,推薦??//遍歷(數組方式)for(int i = 0; i < 3;i++){for(int j = 0;j < 3;j++){printf("%-6d",p[i][j]);//arr的地址  等于  p存儲的值,也就意味著p等價與arr}printf("\n");}?//p++;//此時是可以使用,因為p指向的是arr中的行,默認為首行return 0;}?
  • 寫法2

    ?/*************************************************************************> File Name: ?  demo02.c> Author: ? ? ? 趙生鑫> Description: ?> Created Time: 2025年03月20日 星期四 10時17分55秒************************************************************************/?#include <stdio.h>?int main(int argc,char *argv[]){int arr[][3] = {11,22,33,44,55,66,77,88,99};?//定義一個數組指針指向二維數組arr//int (*p)[][3] = &arr; ? 數組指針指向二維數組,不推薦int (*p)[3] = arr;//數組指針指向二維數組首行,推薦??int rows = sizeof(arr) / sizeof(arr[0]);int cols = sizeof(arr) / sizeof(arr[0]);?for(int i = 0;i < rows;i++){for(int j = 0;j < cols;j++){//三種寫法//1.指針數組語法printf("%-6d",p[i][j]);?//2.指針解引用printf("%-6d",*(*(p + i) + j));?//3.混合法printf("%-6d",(*(p + i))[j]);//解引用符*和數組訪問符[]在一起時,默認的[]優先級高}printf("\n");}??//p++;//此時是可以使用,因為p指向的是arr中的行,默認為首行return 0;}?
指針和數組中的符號優先級

() > [] > *

通過指針引用二維數組

注意:二維數組中,數組整體的地址值 = 數組中0行元素的地址值 = 數組中0行0列元素的地址值

案例

案例1

  • 需求:用指向元素的指針變量輸出二維數組元素的值

  • 代碼:

    ?/*************************************************************************> File Name: ?  demo03.c> Author: ? ? ? 趙生鑫> Description: ?> Created Time: 2025年03月20日 星期四 11時46分00秒************************************************************************/?#include <stdio.h>?int main(int argc,char *argv[]){//定義一個普通二維數組int arr[3][4] = {10,20,30,40,100,200,300,400,1000,2000,3000,4000};?//定義一個指針變量,用來接收二維數組的元素int *p = arr[0];//0列的位置?//獲取元素個數int len = (sizeof(arr) / sizeof(arr[0])) * (sizeof(arr[0]) / sizeof(arr[0][0]));//遍歷數組for(;p < arr[0]+len;p++){//每4個換行if((p - arr[0]) % 4 == 0)printf("\n");printf("%-6d",*p);}printf("\n");??return 0;}?
    ??
指針數組

定義:指針數組是一個數組,數組中的每一個元素都是一個指針

特點:

  • 先有指針,后有數組

  • 指針數組的本質是一個數組,只是數組中的元素類型是指針

語法:

?數據類型 *數組名[容量];
?#include <stdio.h>?int main(){//定義三個變量int a = 10,b = 20,c = 30;//定義指針數組,指針數組是用來存儲指針int *arr[3] = {&a,&b,&c};//獲取數組大小int len = sizeof(arr) / sizeof(arr[0]);//遍歷數組for(int i = 0;i < len; i++){pritnf("%-3d",*arr[i]6);}return 0;}

建議:我們一般使用指針數組處理字符串。

數組指針與指針數組的區別

字符數組和字符指針

字符串實現

再C語言中,表示一個字符串有以下兩種方式:

①數組形式:用字符數組存放一個字符串

②指針形式:用字符指針指向一個字符串

案例
?#include <stdio.h>?/*方式1:使用字符數組實現字符串*/void str_test1(){//定義一個偽字符串char str[] = "  I LOVE YOU";printf("%s\n",str);}??/*方式2:使用字符指針實現字符串*/void str_test2(){//定義一個偽字符串char *str = "I LOVE YOU";printf("%s\n",str);}???int main(){str_test1();str_test2();return 0;}

注意:字符數組和字符指針變量都能實現字符串的存儲與運算。(字符指針→字符類型的指針變量)

字符數組和字符指針的聯系
概念
  • 字符數組由元素組成,每個元素中存放一個字符,而字符指針變量中存放的是地址(可以作為函數參數)

  • 只能對字符數組中的各個元素賦值,而不能用賦值語句對整個字符數組賦值

    ?char arr[3] = {};arr[2] = 'A';//正確,對字符數組中的元素賦值?arr = {'E','D','F'};//錯誤,對整個數組賦值(可以理解為數組就是一個常量,一旦創建,就無法改變)
  • 字符數組名雖然代表地址,但數組名的值不能改變,因為數組名是常量(參照上面案例)

  • 對應字符串中的字符的存取,可以用下標法,也可以用指針法。

案例
?#include <stdio.h>?int mian(){//使用兩種方式測試字符串char str1[] = "你好,佩奇!";char *str2 = "你好,喬治!";//賦值測試str1 = "你好啊,佩奇!!";//數組一旦創建就無法改變其值,可以理解為數組名是常量str2 = "你好啊,喬治!!";//打印測試printf("%s,%s\n",str1,str2);/*//以下代碼會報錯//給字符串賦值char *str3 = NULL;//未初始化的指針,指針一定要有指向,需要指向一個具體的內存空間printf("請輸入一個符串:\n");scanf("%s",str3);printf("%s\n ",str3);*/char a[] = "I LOVE YOU";char *b = "I LOVE YOU";//使用下標法和指針法分別訪問字符串printf("%c,%c\n,%c\n",a[2],*(a+2),b[2],*(b+2))return 0;}
字符串作為形式參數
定義
  • 實參與形參都可以是字符數組

    ?void fun(char str[],int len){...}void mian(){char str[] = "hello";fun(str,sizeof(str) / sizeof(str[0]))}
  • 實參用字符數組,形參用字符指針

    ?void fun(char *str,int len){...}void mian(){char *str = "hello";fun(str,sizeof(str) / sizeof(str[0]))}
  • 形參和實現都是指針變量(在函數內部中不對字符串中的字符做修改)

    ?void fun(char *str,int len){//在函數內部中不對字符串中的字符做修改,否則報段錯誤//*(str + 2) = 'A';//str[2] = 'A';printf("%s\n",str);}void mian(){char *str = "hello";fun(str,sizeof(str) / sizeof(str[0]))}
  • 實參是指針類型,形參是字符數組(在函數內部中不對字符串中的字符做修改)

    ?void fun(char str[],int len){//在函數內部中不對字符串中的字符做修改,否則報段錯誤//*(str + 2) = 'A';//str[2] = 'A';printf("%s\n",str);}void mian(){char *str = "hello";fun(str,sizeof(str) / sizeof(str[0]))}
注意

1.字符數組在創建的時候,會在內存中開辟內存空間,內存空間可以存放字符數據;字符指針在創建的時 候,需要依賴于字符數組,字符指針在內存開辟的內存空間中,存放的是數組元素的地址。字符指針的 創建依賴于字符數組,字符數組可以獨立存在,而字符指針不能獨立存在。 2.字符數組可以初始化,但是不能賦值;字符指針可以初始化,也可以賦值。

案例
案例1
  • 需求:字符指針作為函數參考:用函數調用實現字符串的復制及長度計算

  • 代碼:

    ?/*************************************************************************> File Name: ?  demo04.c> Author: ? ? ? 趙生鑫> Description: ?> Created Time: 2025年03月20日 星期四 16時55分04秒************************************************************************/?#include <stdio.h>?/***定義一個函數,實現字符串的拷貝,返回字符串的長度*@param source拷貝的源字符串*@param target需要拷貝保存字符串的目標字符串*@return 字符串長度** */int str_copy(const char *source,char *target){//定義一個循環變量register int i = 0;?//循環的遍歷while(source[i] != '\0'){//實現拷貝*(target + i) = *(source + i);//指針法?//下標法  target[i] = source[i];?i++;}//拷貝結束后,一定給target加上\0*(target + i) = '\0';??return i;}??int main(int argc,char *argv[]){//定義兩個數組,從鍵盤錄入字符串char source[20],target[20];?printf("請輸入一個字符串:\n");?scanf("%s",source);?//拷貝并復制長度int len = str_copy(source,target);?printf("字符串:%s的長度是%d\n",target,len);?return 0;}?
案例2
  • 需求:字符指針作為函數的參數-給定一個字符串,截取start到end之間的字符串,含頭不含尾

  • 代碼:

    ?/*************************************************************************> File Name: ?  demo05.c> Author: ? ? ? 趙生鑫> Description: ?> Created Time: 2025年03月20日 星期四 17時08分51秒************************************************************************/?#include <stdio.h>?/**定義一個函數,實現字符串的截取(含頭不含尾)*@param source源字符串*@param start開始截取的位置(下標)*@param end結束截取的位置(下標)*@param target截取出來的字符串*@return target的串長** */int str_substr(const char *source,int start,int end,char *target){//定義循環變量(i時source取的下標,k時target存的下標)register int i = 0,k = 0;?//遍歷源字符串while(source[i] != '\0'){//根據start和end截取if(i >= start && i < end){//下標法target[k] = source[i];*(target + k) = *(source + i);k++;}i++;}//target截取結束,需要添加\0*(target + k) = '\0';return k;}??int main(int argc,char *argv[]){char *str = "abcdefg";char target[26];int len = str_substr(str,2,5,target);printf("%s,%s,%d\n",str,target,len);return 0;}

##

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/74094.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/74094.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/74094.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

31天Python入門——第5天:循環那些事兒

你好&#xff0c;我是安然無虞。 文章目錄 1. while循環1.1 while循環的嵌套1.2 補充學習:print函數 2. for循環2.1 range函數2.2 for循環2.3 continue和break以及return2.4 for循環的嵌套 3. 補充學習3.1 enumerate函數3.2 zip函數3.3 不要在遍歷列表的過程中刪除元素 循環 是…

T3 出行:網約車全棧分布式數據庫升級實踐

現今&#xff0c;網約車已成為民眾日常出行不可或缺的選擇。伴隨“互聯網出行”模式的快速推進&#xff0c;龐大的出行數據應運而生&#xff0c;如同構建了城市交通系統的數字神經脈絡。與此同時&#xff0c;對高效數據存儲與深入數據分析的需求也在持續攀升。 T3 出行于2019年…

區塊鏈技術在供應鏈管理中的應用與創新

在當今全球化的商業環境中&#xff0c;供應鏈管理的復雜性與日俱增。從原材料采購到最終產品交付&#xff0c;涉及眾多環節和參與者&#xff0c;信息的透明度、準確性和安全性至關重要。區塊鏈技術的出現&#xff0c;為供應鏈管理帶來了全新的解決方案&#xff0c;正在逐步改變…

藍橋每日打卡--打家劫舍4

#藍橋#JAVA#打家劫舍4 題目描述 沿街有一排連續的房屋。每間房屋內都藏有一定的現金。現在有一位小偷計劃從這些房屋中竊取現金。 由于相鄰的房屋裝有相互連通的防盜系統&#xff0c;所以小偷 不會竊取相鄰的房屋 。 小偷的 竊取能力 定義為他在竊取過程中能從單間房屋中竊…

c#難點整理

1.何為托管代碼&#xff0c;何為非托管代碼 托管代碼就是.net框架下的代碼 非托管代碼&#xff0c;就是非.net框架下的代碼 2.委托的關鍵知識點 將方法作為參數進行傳遞 3.多維數組 4.鋸齒數組 5.多播委托的使用 6.is運算符 相當于邏輯運算符是 7.as 起到轉換的作用 8.可…

Nginx代理本機的443到本機的8080端口

1. 準備工作 確認已生成 IP 的 HTTPS 證書 假設你已通過 mkcert 生成證書&#xff08;如 192.168.199.191.pem 和 192.168.199.191-key.pem&#xff09;&#xff0c;并已安裝 CA 證書&#xff08;運行過 mkcert -install&#xff09;。 Nginx 安裝 ? 若未安裝 Nginx&#…

善用批處理的for命令倍增效率(附彩蛋:windows官方bug)

前言 在我們工作中,如果使用Windows系統,善用批處理命令,特別是在批量的文件處理,文本處理時能幫助我們極大地提升工作效率,起到事半功倍的效果! 但很多同學,對批處理的使用更多還停留在可以將多個command命令組合到一起執行,省去重復敲命令和等待的時間。這個其實只…

數據結構之棧的2種實現方式(順序棧+鏈棧,附帶C語言完整實現源碼)

對于邏輯關系為“一對一”的數據&#xff0c;除了用順序表和鏈表存儲外&#xff0c;還可以用棧結構存儲。 棧是一種“特殊”的線性存儲結構&#xff0c;它的特殊之處體現在以下兩個地方&#xff1a; 1、元素進棧和出棧的操作只能從一端完成&#xff0c;另一端是封閉的&#xf…

Camera2 API拍照失敗問題實錄:從錯誤碼到格式轉換的排坑之旅

一、問題背景 在開發基于Camera2 API的相機應用時&#xff0c;我們遇到了一個棘手的問題&#xff1a;預覽功能在所有設備上工作正常&#xff0c;但在某特定安卓設備上點擊拍照按鈕后無任何響應。值得注意的是&#xff0c;使用舊版Camera API時該設備可以正常拍照。本文記錄了完…

Jmeter舊版本如何下載

1.Jmeter最新版本下載位置 https://jmeter.apache.org/download_jmeter.cgi2.Jmeter舊版本下載位置 https://archive.apache.org/dist/jmeter/binaries穩定版本&#xff1a;5.4.1

css-grid布局

文章目錄 1、布局2、網格軌道3、間距Gap4、網格線5、網格別名 當一個 HTML 元素將 display 屬性設置為 grid 或 inline-grid 后&#xff0c;它就變成了一個網格容器&#xff0c;這個元素的所有直系子元素將成為網格元素。 1、布局 啟用grid布局類似與flex布局&#xff0c;不過g…

SolidWorks使用顯卡教程

操作步驟&#xff1a; 打開注冊表編輯器 按下鍵盤上的 Win R 組合鍵&#xff0c;輸入 regedit 并按回車鍵&#xff0c;打開注冊表編輯器。 導航到顯卡信息路徑 在注冊表中依次展開以下路徑&#xff1a; plaintext HKEY_CURRENT_USER\Software\SolidWorks\SOLIDWORKS 2021\Per…

【C++11】左值引用、右值引用、移動語義和完美轉發

&#x1f984;個人主頁:修修修也 &#x1f38f;所屬專欄:C ??操作環境:Visual Studio 2022 目錄 &#x1f4cc;左值引用和右值引用 &#x1f38f;左值和左值引用 &#x1f38f;右值和右值引用 &#x1f4cc;左值引用和右值引用比較 &#x1f38f;左值引用 &#x1f38f;右值…

麒麟系列Linux發行版探秘

以下內容摘自《銀河麒麟操作系統進階應用》一書。 銀河麒麟操作系統&#xff08;Kylin&#xff09; 銀河麒麟&#xff08;Kylin&#xff09;操作系統是中國自主研發的一款基于Linux內核的操作系統。它的發展歷程可以追溯到2002年&#xff0c;最初由國防科技大學主導研發&…

【機密計算頂會解讀】11:ACAI——使用 Arm 機密計算架構保護加速器執行

導讀&#xff1a;本文介紹ACAI&#xff0c;其構建一個基于CCA的解決方案&#xff0c;使得機密虛擬機能夠安全地使用加速器&#xff0c;同時保持與現有應用程序的兼容性和安全性&#xff0c;能夠實現對加速器的安全訪問。 原文鏈接&#xff1a;ACAI: Protecting Accelerator Ex…

第一天 UnityShader的結構

Shader初學者的學習筆記 第一天 Unity Shader的結構 文章目錄 Shader初學者的學習筆記前言一、Unity Shader結構二、Unity Shader結構解析① Properties② Tags③ RenderSetup(可選狀態)④ Name⑤ [Tags]⑥ [RenderSetup]⑦ 頂點著色器和片元著色器的代碼 (Unity最聰明的孩子)…

VL開源模型實現文本生成圖片

一、 基礎知識 根據描述生成圖片的視覺-語言模型&#xff08;Vision-Language Models, VL 模型&#xff09;是近年來多模態生成領域的熱點研究方向。這些模型能夠根據自然語言描述生成高質量的圖像&#xff0c;廣泛應用于藝術創作、設計輔助、虛擬場景構建等領域。 1 根據描述…

【Java SE】抽象類/方法、模板設計模式

目錄 1.抽象類/方法 1.1 基本介紹 1.2 語法格式 1.3 使用細節 2. 模板設計模式&#xff08;抽象類使用場景&#xff09; 2.1 基本介紹 2.2 具體例子 1.抽象類/方法 1.1 基本介紹 ① 當父類的某些方法&#xff0c;需要聲明&#xff0c;但是又不確定如何實現時&#xff…

【人工智能】LM Studio 的 GPU 加速:釋放大模型推理潛能的極致優化

《Python OpenCV從菜鳥到高手》帶你進入圖像處理與計算機視覺的大門! 解鎖Python編程的無限可能:《奇妙的Python》帶你漫游代碼世界 隨著大語言模型(LLM)的廣泛應用,其推理效率成為限制性能的關鍵瓶頸。LM Studio 作為一個輕量級機器學習框架,通過 GPU 加速顯著提升了大…

深度學習:從零開始的DeepSeek-R1-Distill有監督微調訓練實戰(SFT)

原文鏈接&#xff1a;從零開始的DeepSeek微調訓練實戰&#xff08;SFT&#xff09; 微調參考示例&#xff1a;由unsloth官方提供https://colab.research.google.com/github/unslothai/notebooks/blob/main/nb/Qwen2.5_(7B)-Alpaca.ipynbhttps://colab.research.google.com/git…