繁体   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