日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关于“指针的指针”的认识(值传递、指针传递区分)

發(fā)布時間:2025/3/12 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关于“指针的指针”的认识(值传递、指针传递区分) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

【摘要】對于C語言的參數(shù)傳遞通常都是值傳遞,當(dāng)傳傳遞一個指針給函數(shù)的時,其實質(zhì)上還是值傳遞。我們可以看以下常見的面試題:

#include <stdio.h> #include <stdlib.h> #include <string.h>void function1(int *v) {v = (int *)malloc(sizeof(int));*v = 100; }void main() {int *v = NULL;function1(v);printf("%d\n",*v); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

分析:指針其實本質(zhì)就是一個變量,存放的是地址,不過也是一個值罷了,只不過特殊一點。本段函數(shù)的被調(diào)函數(shù)就把這個值(也就是地址)拷貝了下來。被調(diào)函數(shù)執(zhí)行了 v = (int *)malloc(sizeof(int)); 之后,這樣一條語句主動申請一塊內(nèi)存,并把這塊內(nèi)存的地址返回給v ,悄然把地址修改啦。這時主函數(shù)和被調(diào)函數(shù)中的指針指向的東西沒有半毛關(guān)系了,主函數(shù)中v還是NULL,所以……

1、指針傳遞與值傳遞

我們再來看以一個交換2個數(shù)的值的函數(shù)調(diào)用的代碼:

void swap ( int *a, int *b ){int c;c = *a;*a = *b;*b = c; } int main(int argc, char **argv){int a,b;a = 16;b = 32;swap( &a, &b);return ( a - b ); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

分析:能夠正常交換a,b的值,被調(diào)函數(shù)操作的*a變量解引用一下,其實它的地址和主調(diào)函數(shù)a是一樣的。因此它們操作是在同一塊內(nèi)存區(qū)域,可以實現(xiàn)數(shù)值的交換。

下面貼出一個錯誤的代碼:

void swap ( int *a, int *b ){int *temp;temp = NULL;temp = a;a = b;b = temp; } int main ( int argc, char **argv ){int a,b;a = 16;b = 32;swap(&a, &b);return ( a - b ); }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

分析:這種方式按照理論上來說,是想通過調(diào)用swap函數(shù),在swap函數(shù)內(nèi)部,實現(xiàn)將交換&a,&b,即交換a和b的地址來達到目的。但是被調(diào)函數(shù)只是對a,b的地址進行拷貝,簡單一點說其實就相當(dāng)于值傳遞,即使被調(diào)函數(shù)再一次對a,b地址進行修改,對主調(diào)函數(shù)實參a,b地址是沒有任何影響的。所以根本沒有起到值交換目的的。所以上述代碼是錯誤的,無法實現(xiàn)你想要的功能。

2、指針的指針

當(dāng)我們用二級指針來實現(xiàn)上述功能的時候有就可以達到效果。

#include "stdafx.h" #include <stdio.h> #include <stdlib.h> #include <string.h>void swap ( int **a, int **b ){int *tmp = NULL;tmp = *a;*a = *b;*b = tmp; }int main ( int argc, char **argv ){ int x = 16; int y = 32; int *a = &x;int *b = &y;swap(&a, &b); printf("%d\n",*a-*b);getchar();return 0; }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

分析:這個時候,你會發(fā)現(xiàn)就能實現(xiàn)達到交換的目的。我們通過操作中間橋梁(一級指針 *a)通過交換它們的值,實現(xiàn)數(shù)值交換。

3、指針的指針常見用途

雙指針主要用在但我們想向一個A函數(shù)傳遞參數(shù)的時候,但是我們希望在A內(nèi)部對參數(shù)做任何修改都能保存起來,那么就是用雙指針吧。

舉個例子;
我們在做鏈表的時候,我們肯定希望在用一個函數(shù)creatLink(…)函數(shù)來增加鏈表節(jié)點。那么我們可以有2種方法來實現(xiàn)
第一種,用一級指針

typedef struct node{...... }list; node *create(list *l){list *head;head = l;malloc...//為節(jié)點申請內(nèi)存空間......//操作return head; } int main(...){......list *listheadcreateList(listhead);....//以后的任何操作,我們都要考慮,我們是否拿到的是鏈表頭指針,到底哪是鏈表波的頭指針,我們是否要return下來返回鏈表頭指針?? }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

分析:這樣做可以達到增加節(jié)點的目的,但是,在任何情況下,我們的操作都得死死地抓住頭指針,也即是我們增加節(jié)點后,任何對鏈表長度的修改,我們都要 鏈表頭指針返回,即 return head;所以,我們要通過這個函數(shù)最后獲得頭指針,抓住他,死死地抓住他,然后操作。

第二種方法:用雙指針,也即是二級指針。

typedef struct node{...... }list; void create(list **l){list *head;head = l;malloc...//為節(jié)點申請內(nèi)存空間......//操作 }int main(...){......list *stcreateList(st)...... //以后的任何操作,不管是刪除還是插入,我們不需要考慮,我們是否已經(jīng)return head了,不需要,我們在任何情況下,對鏈表的操作都只需要使用st來完成,因為,st就是鏈表的頭指針,不變,因為在申明st的時候,已經(jīng)為st分配 一個地址空間,它是存在的,一直存在,直到main函數(shù)結(jié)束 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

這里有關(guān)于指針的指針兩篇不錯的博客,推薦給大家
深入理解雙指針的兩種用法
重新認識二級指針(Pointers to Pointers)

總結(jié)

以上是生活随笔為你收集整理的关于“指针的指针”的认识(值传递、指针传递区分)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。