c指針作為參數傳遞以及指針的指針 (轉)


函數參數傳遞的只能是數值,所以當指針作為函數參數傳遞時,傳遞的是指針的值,而不是地址。

#include "stdio.h"
void pointer(int *p)
{
  int a = 11;
  printf("\n\nEnter function");
  printf("\nthe p is point to  %p , addr is %X, *p is %d",p , &p, *p);
  *p =11;
  printf("\nthe p is point to  %p , addr is %X, *p is %d",p , &p, *p);
  p = &a;
  printf("\nthe p is point to  %p , addr is %X, *p is %d",p , &p, *p);

  printf("\nfunction return\n");
}

int main()
{
 int b =22;
 int *p = &b;

 printf("the b address %X\n",&b);
 printf("the p is point to %p , addr is %X, *p is %d",p , &p, *p);
 pointer(p);
 printf("\nthe p is  point to %p , addr is %X, *p is %d\n",p , &p, *p);
}

輸出結果:

the b address 28FF3C
the p is point to 0028FF3C , addr is 28FF38, *p is 22

Enter function
the p is point to  0028FF3C , addr is 28FF20, *p is 22
the p is point to  0028FF3C , addr is 28FF20, *p is 11
the p is point to  0028FF0C , addr is 28FF20, *p is 11
function return

the p is  point to 0028FF3C , addr is 28FF38, *p is 11

1.%p為指針所指向的數據的地址,這里既為變量b的地址。

2.在沒有進入pointer函數之前,變量p存儲的值為28FF3C,變量p的地址為28FF38,*p的值等於b的值等於22

3.進入pointer之后,p所指向的內存地址沒有改變,但是p自身的地址變了。意味着函數傳遞只是將28FF3C傳遞進來了。雖然這個指針變量名字還是叫做p,但與main函數中的指針變量已經不一樣了。這意味着,你可以改變main函數中b的值,但是不能改變p的值

 

函數參數為指針的指針

先看一個例子

#include "stdio.h"

void GetMemory(char *p,int num)
{
    p=(char*)malloc(sizeof(char)*num); 
}

void main()
{
    char *str=NULL;
    GetMemory(str,100); 
    strcpy(str,"hello");
    printf(str);
}

GetMemory這個函數是調用malloc申請一塊內存。乍一看好像沒什么問題,編譯也不會報錯。但是運行起來,程序直接奔潰。 其實有了上面的分析就可以知道,GetMemeory中的p是不能改變str的指向的,也就是說str還是指向NULL。GetMemory中的P是臨時申請的一個指針變量,當str傳值進來(NULL),時,p指向NULL,除此之外,沒做任何改變。當運行malloc函數后,也只是將malloc返回的的指針地址賦給了p,並不能傳遞給str。所以這里就需要指針的指針了

 

#include "stdio.h"

void GetMemory(char **p,int num)
{
    *p=(char*)malloc(sizeof(char)*num); 
}

void main()
{
    char *str=NULL;
    GetMemory(&str,100); 
    strcpy(str,"hello\n");
    printf(str);
}

這個時候就是將指針變量str的地址傳遞了過去,而不是將指針變量的值(NULL)傳遞了過去,因此就可以改變str的指向了。

原文鏈接:https://www.cnblogs.com/WeyneChen/p/6672045.html

 

理解多級指針:

多級指針就是指針的指針的指針...,實際上也沒那么復雜,非常簡單。本節來看看如何理解多級指針。

假如定義了一個二級指針:

int **q;

q 的前面有兩個“*”,這個該如何理解呢?與一級指針的理解是一樣的。

int**q 可以把它分為兩部分看,即 int* 和 (*q),后面 (*q) 中的“*”表示 q 是一個指針變量,前面的 int* 表示指針變量 q 只能存放 int* 型變量的地址。對於二級指針甚至多級指針,我們都可以把它拆成兩部分。首先不管是多少級的指針變量,它都是一個指針變量,指針變量就是一個“*”,其余的“*”表示的是這個指針變量只能存放什么類型變量的地址。比如“int****a;”表示指針變量 a 只能存放 int*** 型變量的地址。

下面來舉一個例子。假如定義了一個指針變量 p 指向一個 int 型變量: 

int i = 10;
int *p = &i;

前面講過,指針變量的“基類型”用來指定該指針變量可以指向的變量的類型,即該指針變量只能存放什么類型變量的地址。所以 int*p 表示 p 指向的是 int 型變量,里面只能存放 int 型變量的地址。雖然 p 是指針變量,但只要是變量就有地址,就可以定義一個指針變量存放它:

int **q = &p;

為什么存放 &p 要兩個“*”呢?因為指針變量 p 的基類型為 int 型,所以 &p 的基類型為 int*型 。所以如果要定義一個能指向 int* 型變量的指針變量,有兩個要求:首先它要是指針變量,即一個“*”;其次,該指針變量指向的是 int* 型的數據,或者說存放的是 int* 型變量的地址,所以就是 int**。

以上就是為什么需要兩個“*”的原因。兩個“*”表示二級指針,就是指針的指針。二級指針需要兩個“*”才能指向最終的內存單元,即 **q==i。變量 q 中存放變量 *q 的地址,變量 *q 中存放變量 **q 的地址,變量 **q 中存放i的內容,即 10。或者說:q 指向 *q,*q 指向 **q,**q 中存放i的內容,即 10。

同樣,雖然 q 存放的是指針變量 p 的地址,但它也有地址。所以也可以定義一個指針變量,里面存放 q 的地址:

int ***r = &q;

int***r 就等價於 int***r,所以 r 的基類型就是 int** 型。而 q 的基類型是 int* 型,所以 &q 的基類型是 int** 型。所以 r 有三個“*”才能指向 q 的地址。三個“*”表示三級指針,即指針的指針的指針。三級指針需要三個“*”才能指向最終的內存單元,即 ***r==i。

下面來寫一個程序:

# include <stdio.h>
int main(void)
{
    int i = 10;
    int *p = &i;
    int **q = &p;
    int ***r = &q;
    printf("i = %d\n", ***r);
    return 0;
}
輸出結果是:
i = 10

這就是多級指針,也很簡單,一定要弄清楚。

原文鏈接:http://c.biancheng.net/view/225.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM