簡體   English   中英

指針或指針到指針

[英]Pointer or Pointer-to-Pointer

在我繼續之前,我想告訴你我是C語言的初學者(6個月),當我不得不在程序中使用指針時,我不是100%肯定它們,所以請對我保持溫和。

今天我正在編寫一些東西,有一次我意識到我需要使用交換。

選項1:這是我使用的:

#include <stdio.h>

void swap(int *pa, int *pb){
    int temp;
    temp = *pa;
    *pa = *pb;
    *pb = temp;
}


int main(void){
    int a = 5;
    int b = 10;

    printf("Before Swap:\n");
    printf("A = %d\nB = %d\n\n",a,b);

    swap(&a,&b);

    printf("After Swap:\n");
    printf("A = %d\nB = %d\n",a,b);

    return 0;
}

它可以滿足我的需求:

 Before Swap: A = 5 B = 10 
After Swap:
A = 10
B = 5

后來我決定在程序中必須包含指針,我這樣更改了程序:

選項2:

#include <stdio.h>

void swap(int *pa, int *pb){
    int temp;
    temp = *pa;
    *pa = *pb;
    *pb = temp;
}


int main(void){
    int a = 5;
    int b = 10;

    int *pa = &a;
    int *pb = &b;

    printf("Before Swap:\n");
    printf("PA = %d\nPB = %d\n\n",*pa,*pb);

    swap(pa,pb);

    printf("After Swap:\n");
    printf("PA = %d\nPB = %d\n",*pa,*pb);

    return 0;
}

再一次,它可以很好地滿足我的需求:

Before Swap:
PA = 5
PB = 10

After Swap:
PA = 10
PB = 5

現在來有趣的部分。 我正在進行編碼,並通過使用Pointer-to-Pointer作為參數來更改交換功能,我得到了:

選項3:

#include <stdio.h>

void swap(int **ppa, int **ppb){
    int temp;
    temp = **ppa;
    **ppa = **ppb;
    **ppb = temp;
}


int main(void){
    int a = 5;
    int b = 10;

    int *pa = &a;
    int *pb = &b;

    printf("Before Swap:\n");
    printf("PA = %d\nPB = %d\n\n",*pa,*pb);

    swap(&pa,&pb);

    printf("After Swap:\n");
    printf("PA = %d\nPB = %d\n",*pa,*pb);

    return 0;
}

一切都很好:

 Before Swap: PA = 5 PB = 10 
After Swap:
PA = 10
PB = 5

因此,當我在main中調用swap函數時,這里必須使用&運算符。 我的問題是(因為我在這里感到困惑)選項2和選項3都可以使用還是應該只使用其中之一,為什么? 我不是在要求更好的編碼,我只是不知道選項2和3是否合法,以及為什么兩者都能正常工作。

LE:@Olaf說:

並且如果您在交換中添加了第三顆或第四顆星,也可以。 考慮一下

現在我更加困惑,因為它不能像他所說的那樣工作:

#include <stdio.h>

void swap(int ****pa, int ****pb){
    int temp;
    temp = ****pa;
    ****pa = ****pb;
    ****pb = temp;
}


int main(void){
    int a = 5;
    int b = 10;

    int *pa = &a;
    int *pb = &b;

    printf("Before Swap:\n");
    printf("PA = %d\nPB = %d\n\n",*pa,*pb);

    swap(&pa,&pb);

    printf("After Swap:\n");
    printf("PA = %d\nPB = %d\n",*pa,*pb);

    return 0;
}

輸出:

 program.c: In function 'main': program.c:21:14: error: passing argument 1 of 'swap' from incompatible pointer type [-Werror] swap(&pa,&pb); ^ program.c:3:10: note: expected 'int ****' but argument is of type 'int **' void swap(int ****pa, int ****pb){ ^ program.c:21:18: error: passing argument 2 of 'swap' from incompatible pointer type [-Werror] swap(&pa,&pb); ^ program.c:3:10: note: expected 'int ****' but argument is of type 'int **' void swap(int ****pa, int ****pb){ ^ cc1: all warnings being treated as errors 

合法且有效時,沒有什么錯。 唯一的考慮是它有用和有效的程度。 將指針傳遞給指針,生成的代碼將包含一個三重尋址,第一個尋址將檢索指向該變量的指針的地址,第二個尋址將從該指針中檢索變量的地址,最后它將獲取該變量。 在您的情況下,您必須傳遞指針,以使函數交換能夠修改函數范圍之外的兩個參數。

但是,如果考慮以下代碼,則傳遞指針的指針可能會有所幫助:

#include <stdio.h>

void swap(int **ppa, int **ppb){
    int *pTemp = *ppb;
    *ppb = *ppa;
    *ppa = pTemp;
}


int main(void){
    int a = 5;
    int b = 10;

    int *pa = &a;
    int *pb = &b;

    printf("Before Swap:\n");
    printf("PA = %d\nPB = %d\n\n",*pa,*pb);

    swap(&pa,&pb);

    printf("After Swap:\n");
    printf("PA = %d\nPB = %d\n",*pa,*pb);

    return 0;
}

在這種情況下,您交換的是指針,而不是變量。 當您需要交換大數據(例如字符串)時,這非常有用,因為它比在對象之間復制整個數據要快得多。

您應該很好地理解指針和引用之間的區別以獲得正確的結果

您也應該知道按值,按指針和按引用調用函數之間的區別:

這里有一些例子可以向您闡明這個概念:

 int myAge=39;

cout<< "myAge is locate at " << &myAge << endl; // address of myAge in memory

int* agePtr=&myAge;

cout<<"Address of pointer "<< agePtr << endl;

cout<< " Data at memory address "<< *agePtr << endl;

int badNums[5]={4, 13, 14, 24, 34};

int* numArrayPtr = badNums;

cout<< "Address " << numArrayPtr << " Value " << *numArrayPtr << endl;

numArrayPtr++; // get next value in Array

cout<< "Address " << numArrayPtr << " Value " << *numArrayPtr << endl;

cout<< "Address " << badNums << " Value " << *badNums << endl;

這里通過指針和引用調用函數參數:

void makeMeYoung(int* age) {

 cout<< " I used to be " << *age << endl;

    *age = 21;
  } 

void actYourAge(int& age){
     age = 39;                                       
  }

makeMeYoung(&myAge);

cout << "I'm "<< myAge << " years old now" << endl; // 21

int& ageRef= myAge;

cout<<"myAge : " << myAge << endl; // 21

 ageRef++;

 cout<<"myAge : " << myAge << endl; // 22

actYourAge(ageRef);

cout<<"myAge : " << myAge << endl; // 39

請注意,如果您不想在變量的初始化時初始化,也應該使用指針,並且如果您需要為該指針分配另一個變量,那么使用指針您將可以處理多個變量,而在需要使用時可以進行刷新只是對一個變量使用了一個引用並一直使用它,其想法是當您只想指向一個使用變量的變量時。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM