2010-02-02 55 views

回答

95

這也恰好,如果你想,當你有一個指針來訪問一個實例,反之亦然:

struct foo 
{ 
    int x, y, z; 
}; 

struct foo a, *b = &a; 

b.x = 12; /* This will generate the error, should be b->x or (*b).x */ 

正如在評論中指出,這是可以,如果有人去和typedef做出痛苦SA指針,即包括在typedef的*,像這樣:

typedef struct foo* Foo; 

,因爲你得到的代碼看起來它的處理情況,而實際上它在處理點ERS:

Foo a_foo = get_a_brand_new_foo(); 
a_foo->field = FANTASTIC_VALUE; 

注意如何上面看起來好像它應該寫成a_foo.field,但由於Foo是一個指向struct會失敗。我強烈建議針對typedef:C.指針在C.指針是重要的,不要隱藏你的星號。讓他們閃耀。

+8

我敢打賭,這是實際的問題。它有時還會咬我,*特別是*如果某人有typedef的指針類型。 – 2010-02-02 15:04:26

+1

我只是補充說,如果一個數組沒有被分配(malloc)並且被訪問,這個錯誤就會出現。 – max 2012-03-14 16:35:54

16

您正在嘗試訪問結構的成員,但在某個不是結構的東西中。例如:

struct { 
    int a; 
    int b; 
} foo; 
int fum; 
fum.d = 5; 
0

也可能出現,如果:的

struct foo { int x, int y, int z }foo; 

foo.x=12 

代替

struct foo { int x; int y; int z; }foo; 

foo.x=12 
+0

這兩個陳述之間沒有區別? – 2016-04-15 19:05:25

+0

@NickPredey我看到3個區別... – 2016-11-09 09:16:57

+1

@AlaaM。幾個月後回顧它,我錯過了分號! – 2016-11-09 22:17:28

4

它也可能在以下情況下發生:

如。如果我們考慮堆棧的推送功能:

typedef struct stack 
{ 
    int a[20]; 
    int head; 
}stack; 

void push(stack **s) 
{ 
    int data; 
    printf("Enter data:"); 
    scanf("%d",&(*s->a[++*s->head])); /* this is where the error is*/ 
} 

main() 
{ 
    stack *s; 
    s=(stack *)calloc(1,sizeof(stack)); 
    s->head=-1; 
    push(&s); 
    return 0; 
} 

錯誤在推送功能和註釋行中。指針s必須包含在圓括號內。正確的代碼:

scanf("%d",&((*s)->a[++(*s)->head])); 
+2

謝謝你使指針指向(語言上沒有可怕的玩法)。其他答案提到它(例如「讓你的指針閃耀」),但在凌晨2點與GDB和Valgrind進行的一場史詩般的戰鬥中掙扎時,像我這樣的人意識到你的回答明確地表明瞭指針如何成爲問題以及如何糾正這個問題。 – 2016-05-06 03:16:42

1

這可能意味着您忘記了包含定義此結構/聯合的頭文件。 例如:

了foo.h文件:

typedef union 
{ 
    struct 
    { 
     uint8_t FIFO_BYTES_AVAILABLE : 4; 
     uint8_t STATE     : 3; 
     uint8_t CHIP_RDY    : 1; 
    }; 
    uint8_t status; 
} RF_CHIP_STATUS_t; 

RF_CHIP_STATUS_t getStatus(); 

的main.c文件:

. 
. 
. 
if (getStatus().CHIP_RDY) /* This will generate the error, you must add the #include "foo.h" */ 
. 
. 
. 
1

我有可能列舉其中可以在下面的代碼出現此錯誤,其意見的所有情況。請增加它,如果你遇到更多的案件。

#include<stdio.h> 
#include<malloc.h> 

typedef struct AStruct TypedefedStruct; 

struct AStruct 
{ 
    int member; 
}; 

void main() 
{ 
    /* Case 1 
     ============================================================================ 
     Use (->) operator to access structure member with structure pointer, instead 
     of dot (.) operator. 
    */ 
    struct AStruct *aStructObjPtr = (struct AStruct *)malloc(sizeof(struct AStruct)); 
    //aStructObjPtr.member = 1;  //Error: request for member ‘member’ in something not 
             //a structure or union. 
             //It should be as below. 
    aStructObjPtr->member = 1; 
    printf("%d",aStructObjPtr->member); //1 


    /* Case 2 
     ============================================================================ 
     We can use dot (.) operator with struct variable to access its members, but 
     not with with struct pointer. But we have to ensure we dont forget to wrap 
     pointer variable inside brackets. 
    */ 
    //*aStructObjPtr.member = 2;  //Error, should be as below. 
    (*aStructObjPtr).member = 2; 
    printf("%d",(*aStructObjPtr).member); //2 


    /* Case 3 
     ============================================================================= 
     Use (->) operator to access structure member with typedefed structure pointer, 
     instead of dot (.) operator. 
    */ 
    TypedefedStruct *typedefStructObjPtr = (TypedefedStruct *)malloc(sizeof(TypedefedStruct)); 
    //typedefStructObjPtr.member=3; //Error, should be as below. 
    typedefStructObjPtr->member=3; 
    printf("%d",typedefStructObjPtr->member); //3 


    /* Case 4 
     ============================================================================ 
     We can use dot (.) operator with struct variable to access its members, but 
     not with with struct pointer. But we have to ensure we dont forget to wrap 
     pointer variable inside brackets. 
    */ 
    //*typedefStructObjPtr.member = 4; //Error, should be as below.  
    (*typedefStructObjPtr).member=4; 
    printf("%d",(*typedefStructObjPtr).member); //4 


    /* Case 5 
     ============================================================================ 
     We have to be extra carefull when dealing with pointer to pointers to 
     ensure that we follow all above rules. 
     We need to be double carefull while putting brackets around pointers. 
    */ 

    //5.1. Access via struct_ptrptr and -> 
    struct AStruct **aStructObjPtrPtr = &aStructObjPtr; 
    //*aStructObjPtrPtr->member = 5; //Error, should be as below. 
    (*aStructObjPtrPtr)->member = 5; 
    printf("%d",(*aStructObjPtrPtr)->member); //5 

    //5.2. Access via struct_ptrptr and . 
    //**aStructObjPtrPtr.member = 6; //Error, should be as below. 
    (**aStructObjPtrPtr).member = 6; 
    printf("%d",(**aStructObjPtrPtr).member); //6 

    //5.3. Access via typedefed_strct_ptrptr and -> 
    TypedefedStruct **typedefStructObjPtrPtr = &typedefStructObjPtr; 
    //*typedefStructObjPtrPtr->member = 7; //Error, should be as below. 
    (*typedefStructObjPtrPtr)->member = 7; 
    printf("%d",(*typedefStructObjPtrPtr)->member); //7 

    //5.4. Access via typedefed_strct_ptrptr and . 
    //**typedefStructObjPtrPtr->member = 8; //Error, should be as below. 
    (**typedefStructObjPtrPtr).member = 8; 
    printf("%d",(**typedefStructObjPtrPtr).member); //8 

    //5.5. All cases 5.1 to 5.4 will fail if you include incorrect number of * 
    //  Below are examples of such usage of incorrect number *, correspnding 
    //  to int values assigned to them 

    //(aStructObjPtrPtr)->member = 5; //Error 
    //(*aStructObjPtrPtr).member = 6; //Error 
    //(typedefStructObjPtrPtr)->member = 7; //Error 
    //(*typedefStructObjPtrPtr).member = 8; //Error 
} 

的基本思路是直:

  • 使用.與結構變量。 (情況2和4)
  • 使用->指向結構。 (例1和3)
  • 如果達到結構變量或指針通過以下指針結構變量,然後再包內支架中的指針:(*ptr).(*ptr)-> VS *ptr.*ptr->(除了殼體1的所有情況下)
  • 如果通過跟隨指針到達,確保你已經正確地到達了指向結構體或結構體的指針。 (案例5,特別是5.5)
相關問題