简体   繁体   English

在指针数组中打印指针指向的值

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

  1. I am trying to print the values pointed by pointers stored inside ptr array.我正在尝试打印存储在 ptr 数组中的指针所指向的值。 Expected output is 1,2,3,4 but the function prints the garbage.预期 output 是 1,2,3,4 但 function 打印垃圾。
  2. Trying to understand how to access values within array and print them.试图了解如何访问数组中的值并打印它们。

I know there's an easy way to just use double pointer to point to array and print but for learning sake trying to not use double pointer and just use pointer to whole array我知道有一种简单的方法可以只使用双指针指向数组并打印,但为了学习,尽量不要使用双指针而只使用指向整个数组的指针

#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;
}

Your code seems unnecessarily complex but I guess you can do below.您的代码似乎不必要地复杂,但我想您可以在下面做。

#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;
}
    

The type of ptr parameter of foo() function is uint8_t* (*) [4] , which is - pointer to an array of 4 uint8_t pointers. foo() function 的ptr参数类型为uint8_t* (*) [4] ,即 - 指向4 uint8_t指针数组的指针。

In the foo() function, the problem is in this statement:foo() function 中,问题出在这个语句中:

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

From definition of the subscript operator 1) , here,根据下标运算符1)的定义,这里,

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

the type of *ptr is uint8_t * [4] . *ptr的类型是uint8_t * [4] So, you are initialising a uint8_t * type variable temp from uint8_t * [4] type variable ptr[0] .因此,您正在从uint8_t * [4]类型变量ptr[0]初始化一个uint8_t *类型变量temp Hence, the initialisation of temp is from an incompatible type resulting in garbage value when accessing it.因此, temp的初始化来自不兼容的类型,导致访问它时产生垃圾值。 It is just that the cast is suppressing the compiler warning.只是演员正在抑制编译器警告。 Remove the cast and closely check the compiler warning.删除强制转换并仔细检查编译器警告。

Instead, you should initialise temp in for loop with every i th element of (*ptr) array, like this相反,您应该使用(*ptr)数组的每个第i元素在for循环中初始化temp ,如下所示

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

and dereferencing temp will give value at that location.并且取消引用temp将在该位置产生价值。

The type of (*ptr)[i] is uint8_t * , how? (*ptr)[i]的类型是uint8_t * ,怎么样? Think of it in this way -这样想——

the type of ptr is uint8_t * (*) [4] , ptr的类型是uint8_t * (*) [4]
the type of *ptr is uint8_t * [4] , and *ptr的类型是uint8_t * [4] ,并且
the type of (*ptr)[i] is uint8_t * , where 0<=i<=3 , (which is same as type of temp variable). (*ptr)[i]的类型是uint8_t * ,其中0<=i<=3 ,(与temp变量的类型相同)。

Also, you should use the format specifier macros for printing fixed width integer types 2) .此外,您应该使用格式说明符宏来打印固定宽度 integer 类型2)

...but for learning sake trying to not use double pointer and just use pointer to whole array... ...但是为了学习,尽量不使用双指针,而只使用指向整个数组的指针...

You don't need the temp pointer to print the values, you can directly print them using ptr pointer (parameter of foo() function).您不需要temp指针来打印值,您可以使用ptr指针( foo()函数的参数)直接打印它们。
You can do:你可以做:

#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: 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). 1)。 From C11 Standard#6.5.2.1:从 C11 标准#6.5.2.1:

The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2))) .下标运算符[]的定义是E1[E2]等同于(*((E1)+(E2)))

2). 2)。 If you are using fixed width integer types ( uint8_t , uint16_t , int8_t , int16_t , uint32_t .... etc.) then you should use their respective conversion specifiers macros specified by language standards to print them.如果您使用的是固定宽度 integer 类型( uint8_tuint16_tint8_tint16_tuint32_t .... 等),那么您应该使用它们各自由语言标准指定的转换说明符宏来打印它们。 The fprintf() family function macro for unsigned decimal integer value is PRIuN where N represents the width ( 8 , 16 , 32 etc..) of type.用于无符号十进制32fprintf()系列16宏的值为PRIuN ,其中N表示类型的宽度( 8等)。 Check macros for format specifiers .检查格式说明符的宏
Also, for these macros, you need to include inttypes.h header file in your program and no need to include stdint.h header file because inttypes.h header file includes stdint.h .此外,对于这些宏,您需要在程序中包含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