簡體   English   中英

在指針數組中打印指針指向的值

[英]Printing value pointed by pointer within array of pointer

  1. 我正在嘗試打印存儲在 ptr 數組中的指針所指向的值。 預期 output 是 1,2,3,4 但 function 打印垃圾。
  2. 試圖了解如何訪問數組中的值並打印它們。

我知道有一種簡單的方法可以只使用雙指針指向數組並打印,但為了學習,盡量不要使用雙指針而只使用指向整個數組的指針

#include <stdio.h>
#include <stdint.h>

uint8_t a = 1;
uint8_t b = 2;
uint8_t c = 3;
uint8_t d = 4;

uint8_t *ptr[] = {&a, &b, &c ,&d}; //Pointer is array of 4 pointer to uint8_t 


void foo(uint8_t* (*ptr)[4]) //Ptr is pointer to array of 4 pointer to uint8_t
{
    uint8_t * temp =(uint8_t*)ptr[0];
    for(uint8_t i=0;i<4;i++){
        
        printf("%d\n",*(temp+i)); //Does not print 1,2,3,4 as expected
    }
}

int main()
{
  
    foo(&ptr);
    return 0;
}

您的代碼似乎不必要地復雜,但我想您可以在下面做。

#include <stdio.h>
#include <stdint.h>

uint8_t a = 1;
uint8_t c = 3;
uint8_t b = 2;
uint8_t d = 4;

uint8_t *ptr[] = {&a, &b, &c ,&d};  


void foo(uint8_t* (*ptr)[4])  
{
    uint8_t ** temp =(uint8_t**)*ptr; 
    for(uint8_t i=0;i<4;i++){
     
        printf("%d\n",**(temp+i)); 
    }
}

int main()
{
  
    foo(&ptr);
    return 0;
}
    

foo() function 的ptr參數類型為uint8_t* (*) [4] ,即 - 指向4 uint8_t指針數組的指針。

foo() function 中,問題出在這個語句中:

uint8_t* temp =(uint8_t*)ptr[0];

根據下標運算符1)的定義,這里,

ptr[0]  ->  *(ptr + 0) -> *(ptr) -> *ptr

*ptr的類型是uint8_t * [4] 因此,您正在從uint8_t * [4]類型變量ptr[0]初始化一個uint8_t *類型變量temp 因此, temp的初始化來自不兼容的類型,導致訪問它時產生垃圾值。 只是演員正在抑制編譯器警告。 刪除強制轉換並仔細檢查編譯器警告。

相反,您應該使用(*ptr)數組的每個第i元素在for循環中初始化temp ,如下所示

uint8_t * temp = (*ptr)[i];   // type of (*ptr)[i] is uint8_t *

並且取消引用temp將在該位置產生價值。

(*ptr)[i]的類型是uint8_t * ,怎么樣? 這樣想——

ptr的類型是uint8_t * (*) [4]
*ptr的類型是uint8_t * [4] ,並且
(*ptr)[i]的類型是uint8_t * ,其中0<=i<=3 ,(與temp變量的類型相同)。

此外,您應該使用格式說明符宏來打印固定寬度 integer 類型2)

...但是為了學習,盡量不使用雙指針,而只使用指向整個數組的指針...

您不需要temp指針來打印值,您可以使用ptr指針( foo()函數的參數)直接打印它們。
你可以做:

#include <stdio.h>
#include <inttypes.h>

uint8_t a = 1;
uint8_t b = 2;
uint8_t c = 3;
uint8_t d = 4;

uint8_t *ptr[] = {&a, &b, &c, &d}; //Pointer is array of 4 pointer to uint8_t 

void foo(uint8_t* (*ptr)[4]) {
    for (uint8_t i = 0; i < 4; i++) {
        /*
         * Using pointer to whole array to print the values
         */      
        printf("Using pointer to whole array : %" PRIu8 "\n", *(*ptr)[i]);

        /* 
         * Print values using temp pointer
         */
        uint8_t* temp = (*ptr)[i];
        /* 
         * temp is pointing to i'th element of (*ptr) array.
         * Dereference temp will give value at that location.
         */
        printf("Using temp pointer : %" PRIu8 "\n", *temp);

    }
}

int main (void) {
    foo (&ptr);
    return 0;
}

Output:

Using pointer to whole array : 1
Using temp pointer : 1
Using pointer to whole array : 2
Using temp pointer : 2
Using pointer to whole array : 3
Using temp pointer : 3
Using pointer to whole array : 4
Using temp pointer : 4

1)。 從 C11 標准#6.5.2.1:

下標運算符[]的定義是E1[E2]等同於(*((E1)+(E2)))

2)。 如果您使用的是固定寬度 integer 類型( uint8_tuint16_tint8_tint16_tuint32_t .... 等),那么您應該使用它們各自由語言標准指定的轉換說明符宏來打印它們。 用於無符號十進制32fprintf()系列16宏的值為PRIuN ,其中N表示類型的寬度( 8等)。 檢查格式說明符的宏
此外,對於這些宏,您需要在程序中包含inttypes.h header 文件,並且無需包含stdint.h header 文件,因為inttypes.h Z099FB995346F31C7549F6E400Z 文件包含stdint.h

暫無
暫無

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

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