網站首頁 編程語言 正文
簡單的案例
深夜無聊而引發的問題
一般來說,在C語言中一個函數頂多只能返回一個值,那么我們如何設計能巧妙的返回多個我們需要的值呢?
先來看簡單的題,我們有一個長度為10的int型數組
int arr[] = {1,8,10,2,-5,0,7,15,4,-5};
現在我們需要寫一個函數,找出此數組中最大值和最小值。
滑稽.jpg(若是不用寫函數,直接通過for遍歷我們直接就能遍歷到最大值和最小值)
但可惡的是必須用函數來解決,此時函數中只能返回一個值,那我們是不是非得寫兩個函數?
我們完全可以通過指針的特性,從函數中取得多個我們需要的“值”
回歸正題
我們在main函數中 定義我們需要用到的指針
int *pmax,*pmin;
接下來 來寫我們的功能函數
void find_max_and_min(int **pmax,int **pmin, int arr[]) {
?? ?*pmax = *pmin = arr;
?? ?int i;
?? ?
?? ?for(i=0;i<10;i++) {
?? ??? ?if(**pmax < arr[i]) {
?? ??? ??? ?*pmax = arr+i;
?? ??? ?}
?? ??? ?if(**pmin > arr[i]) {
?? ??? ??? ?*pmin = arr+i;
?? ??? ?}
?? ?}
}
此時我們注意到,功能函數中傳入的參數分布為兩個指向指針的指針,以及我們需要查找的數組。
主函數中
int *pmax,*pmin;
find_max_and_min(&pmax,&pmin,arr);?
printf("%d,%d",*pmax,*pmin);
即可在arr中找出我們需要的“返回值”
敲重點,敲重點:我們將 指針 pmax和pmin的地址 傳給了函數find_max_and_min。
完整代碼:
#include<stdio.h>
#include<stdlib.h>
void find_max_and_min(int **pmax,int **pmin, int arr[])?
{
?? ?*pmax = *pmin = arr;
?? ?int i=0;
?? ?for (i;i<10;i++)?
?? ?{
?? ??? ?if(**pmax < arr[i])?
?? ??? ?{
?? ??? ??? ?*pmax = arr+i;
?? ??? ?}
?? ??? ?if(**pmin > arr[i])?
?? ??? ?{
?? ??? ??? ?*pmin = arr+i;
?? ??? ?}
?? ?}
}
int main()?
{
?? ?int arr[] = {1,8,10,2,-5,0,7,15,4,-5};
?? ?int *pmax,*pmin;
?? ?find_max_and_min(&pmax,&pmin,arr);
?? ?printf("%d,%d",*pmax,*pmin);
?? ?return 0;
}
簡單的案例2.0
鏈表中"迷人"的指針
typedef struct LNode {
? ? Elemtype data;
? ? struct LNode *next;
}LNode,*LinkList;
這是之前上數據結構課的鏈表代碼,從老師的代碼中不難發現分別定義了LNode和 *LinkList
當時心想: “已經定義了 LNode,要用到結構體指針的時候 直接*LNode就好了,為啥還要定義個 *LinkList 呢 ” 后來逐漸恍然大悟~
凡事先看主函數
int main()
{
? ? LinkList head; ? ? //head 頭指針?
? ? createlist(&head);
? ? initlist(head);
? ? findrabbit(head);
? ? printf("\n");?
? ? outputlist(head);
? ? return 0;
}
這里的 LinkList head; 相當于 LNode * head;
敲重點敲重點,createlist(&head);
嗯哼 此時并沒有任何返回的指針,是在head頭基礎上進行操作的。
并且,在createlist函數中是對 頭指針(head) 進行 取地址(&head),和我們上面的 &pmax,&pmin妙處相同。(沒理解的同學認真想想)
void createlist(LinkList *head)
{
? ? int i;
? ? *head=(LinkList)malloc(sizeof(LNode));
? ??
? ? (*head)->data = 0;
? ? LinkList p,tem;
? ? tem = *head;
?? ?
//?? ?頭插法 循環單鏈表 ?
? ? for(i=0;i<NUMS;i++)
? ? {
? ? ? ? p=(LinkList)malloc(sizeof(LNode));
? ? ? ? tem->next = p;
? ? ? ? tem = p;
? ? ? ??
// ? ? ? ?(*head)->data++; ? //計數用?
? ? }
?? ?tem->next = *head;
}
這里的LinkList *head 等價于 LNode **head
終于理解了老師代碼用心之處~~
再度分析
傳值和傳指針,其實都是傳值。 你需要傳的是指向指針的地址,并通過函數對這個地址中的內容進行操作
指針本身也是一個變量類型,無論變量如何,都應該使用地址傳參,使用取地址符:&
另外再給學數據結構的同學兩種使用結構體進行操作的寫法
寫法一:直接通過函數返回指針:
LinkList init(LinkList L) {
?? ?L = (LinkList)malloc(sizeof(LNode));
?? ?...
?? ?return L
}
int main() {
?? ?LinkList L;
?? ?L = init(L);
}
寫法二:向函數傳遞指針變量的地址,通過函數修改其指向的內容
void init(LinkList *L) {
?? ?*L = (LinkList)malloc(sizeof(LNode));
?? ?...
}
int main() {
?? ?LinkList L;
?? ?init(&L);
}
重在理解。
總結
原文鏈接:https://blog.csdn.net/wanmiqi/article/details/111238735
- 上一篇:沒有了
- 下一篇:沒有了
相關推薦
- 2022-03-11 C語言中static的使用介紹_C 語言
- 2022-05-26 為Jenkins添加SSH全局憑證_相關技巧
- 2022-02-28 CommonsChunkPlugin 插件使用方法 、 出現報錯 : Error: webpa
- 2022-04-11 解決git push出現error: failed to push some refs to 錯誤
- 2023-01-15 詳解Qt中線程的使用方法_C 語言
- 2022-05-06 SQLite3+Qt開發:SQLite3簡要介紹+在Qt5中使用步驟
- 2023-02-18 python常用操作之使用多個界定符(分隔符)分割字符串的方法實例_python
- 2022-05-06 React自定義Hook-useForkRef的具體使用_React
- 欄目分類
-
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支