C指針(2)——指針在函數中的應用(程式講解)

来源:https://www.cnblogs.com/happying30/archive/2018/07/27/9379465.html
-Advertisement-
Play Games

3-1.c指針用作函數參數 目的:是為了通過swapdate()函數把實參x,y的值進行交換,上述例子是將形參dat_x,dat_y的值進行交換,但是形參的交換並沒有改變實參的交換,因為函數在調用時給形參分配了單獨的記憶體空間,實參的值傳遞給形參實際是把實參的值放在形參的記憶體空間,形參的值是實參的備份 ...


3-1.c指針用作函數參數

#include<stdio.h>
  typedef unsigned char uint8_t;   //類型自定義,通過typedef語句重新把unsigned char命名為uint8_t,目的為了方便
  extern void swapdata(uint8_t dat_x,uint8_t dat_y);
int main(void)
{
  uint8_t x,y;
  printf("請輸入x,y:");
  scanf("%d,%d",&x,&y);
  printf("交換前:x=%d,y=%d\n",x,y);
  swapdata(x,y);
  printf("交換後:x=%d,y=%d\n",x,y);
  return 0;
}
  void swapdata(uint8_t dat_x,uint8_t dat_y)  
{
  uint8_t temp;
  temp=dat_x;
  dat_x=dat_y;
  dat_y=temp;
}

目的:是為了通過swapdate()函數把實參x,y的值進行交換,上述例子是將形參dat_x,dat_y的值進行交換,但是形參的交換並沒有改變實參的交換,因為函數在調用時給形參分配了單獨的記憶體空間,實參的值傳遞給形參實際是把實參的值放在形參的記憶體空間,形參的值是實參的備份,因此形參交換,實參並不會交換,不能達到交換實參的目的。 

 結果:

請輸入x,y:30,20
交換前:x=30,y=20
交換後:x=30,y=20

 

3-2 函數調用時,把指針作為函數參數進行傳遞,即傳遞變數的地址。在被調函數中,通過指針操作相應的變數,實際操作變數本身。在被調函數中對形參的操作實際就是對實參的操作。

#include <stdio.h>
typedef unsigned char uint8_t;
extern void swapdata(uint8_t *dat_x,uint8_t *dat_y);  //函數參數變成指針
int main(void)
{
  uint8_t x,y;
  uint8_t *p_x,*p_y;
  printf("請輸入x,y:");
  scanf("%d,%d",&x,&y);
  p_x=&x;
  p_y=&y;
  printf("交換前:x=%d,y=%d\n",x,y);
  swapdata(p_x,p_y);
  printf("交換後:x=%d,y=%d\n",x,y);
  return 0;
}
  void swapdata(uint8_t *dat_x,uint8_t *dat_y)   //形參為兩個指針變數,目的是為了承接實參的值,實參是指針類型,
{
  uint8_t temp;
 temp=*dat_x;    //通過取值運算符*與指針變零dat_x結合,訪問實參x;調用swapdate()後,指針變數dat_x指向實參x,對*dat_x的操作實際是對實參x的操作。
 *dat_x=*dat_y;
 *dat_y=temp;
}

 結果:

請輸入x,y:10,20
交換前:x=10,y=20
交換後:x=20,y=10

  對比3-1和3-2的根本區別是:前者調用函數,實參是x,y的值;後者調用函數時,實參是x,y的指針,即二者的地址。

      結論:要在被調函數中改變主調函數中的變數值,需要將主函數中變數的指針作為實參,傳遞給被調函數。

 

3-3指向結構體的指針變數作為函數參數

#include<stdio.h>
#define BUF_LEN_MAX 3         //巨集定義定義buf的大小
#define DATA_LEN_MAX 3        //定義存放data欄位的buf大小
typedef unsigned char uint8_t;  //給unisigned char 命名為uint8_t
typedef struct
{
  uint8_t head;
  uint8_t len;
  uint8_t add;
  uint8_t data[DATA_LEN_MAX];
  uint8_t chk;
}RF_FRAME;                    //定義結構體,用typedef語句把結構體重新命名為RF_FRAME,然後用該類型定義其他變數
RF_FRAME txbuf[BUF_LEN_MAX]={{0xAA,5,0x00,0x11,0x12,0x13,0x14},    //定義一個RF_FRAME類型的數組txbuf[]數組,併進行初始化;該數組的所有元素都是RF_FRAMR類型,包含head,len,add,data[],chk等成員
                              {0xAA,5,0x01,0x12,0x13,0x13,0x14},
                              {0xAA,5,0x02,0x13,0x14,0x13,0x14}};
void output(RF_FRAME *p_ptr);
int main(void)
{
   RF_FRAME *ptr_tmp;         //定義RF_FRAME的指針變數ptr_tmp
   ptr_tmp=txbuf;             //給指針變數ptr_tmp進行賦值,讓它指向txbuf。即ptr_tmp是指向結構體的指針變數
   output(ptr_tmp);          
   return 0;
}
void output(RF_FRAME *p_ptr)    //傳遞實參ptr_tmp的值,因為是指針變數,實際是讓形參p_ptr指向實參ptr_tmp所指向的數據。也就是實參ptr_tmp和形參p_ptr同時指向數組bxbuf[]
{
   uint8_t i,j;
   for(i=0;i<BUF_LEN_MAX;i++)
  {
      printf(" %x", p_ptr[i].head);    //p_ptr指向數組txbuf[],所以p_ptr[i].head相當於txbuf[i].head
      printf(" %x", p_ptr[i].len);
      printf(" %x", p_ptr[i].add);
       for(j=0;j<DATA_LEN_MAX;j++)
        {
          printf(" %x", p_ptr[i].data[j]);
         }
      printf(" %x\n", p_ptr[i].chk);
   }
} 

  結果:

 aa 5 0 11 12 13 14
 aa 5 1 12 13 13 14
 aa 5 2 13 14 13 14

  

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1. 學習計劃 1、solr集群搭建 2、使用solrj管理solr集群 3、把搜索功能切換到集群版 4、添加商品同步索引庫。 a) Activemq b) 發送消息 c) 接收消息 2. 什麼是SolrCloud SolrCloud(solr 雲)是Solr提供的分散式搜索方案,當你需要大規模,容 ...
  • 一、屬性(特性) 普通方法去執行的時候,後面需要加括弧,特性方法執行的時候和靜態欄位一樣不需要不需要加括弧. 特性方法不和欄位同名. 特性方法不能傳參數. 獲取特性 設置特性 設置特性方法的時候,所需要加的裝飾器名字規則是,你所設置特性方法名字點setter(例如:@end.setter) 這個特性 ...
  • 運行結果: ...
  • 最近在面試過程中,遇到許多抽象類和介面的面試題,所以今天特意研究了下,然後寫出來分享給大家,希望對面試的朋友有幫助,如果覺得寫的可以點個贊吧! 1:抽象類可以實例化,抽象類可以通過子類間接的實例化父類,介面不能實例化。 2:抽象類可以擁有私有屬性、方法,介面不能擁有。 3:抽象類方法不能使用defa ...
  • C++11新特性: auto: auto讓編譯器通過初始值來推算變數的類型。 auto定義的變數必須有初始值。 auto聲明的所有變數的初始基本數據類型都必須一樣。 decltype: decltype的作用是選擇返回操作數的數據類型。 編譯器分析表達式並得到它的類型,卻不計算表達式的值。 如果de ...
  • Given a string, find the length of the longest substring without repeating characters. Examples: Given "abcabcbb", the answer is "abc", which the leng ...
  • 15.1 動態代理 在之後學習Spring框架時,Spring框架有一大核心思想,就是AOP,(Aspact-Oriented-Programming 面向切麵編程) 而AOP的原理就是Java的動態代理機制,在Java的動態代理機制中,有兩個重要的類或介面,一個是 InvocationHandle ...
  • 【前言】對於像我一樣的新手來說,我覺得此環節難點主要是相關依賴包的安裝和Flask-SQLAlchemy的使用,下麵將一一講解: 所謂數據模型,百度的解釋是:“數據模型(Data Model)是數據特征的抽象。數據(Data)是描述事物的符號記錄,模型(Model)是現實世界的抽象。數據模型從抽象層 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...