2015-11-09 33 views
2

該程序的目的是使用指針將名稱分配給相應的年齡。C程序:使用指針需要幫助

#include <stdio.h> 
#include <stdlib.h> 

/* these arrays are just used to give the parameters to 'insert', 
    to create the 'people' array 
*/ 

#define HOW_MANY 7 
char *names[HOW_MANY]= {"Simon", "Suzie", "Alfred", "Chip", "John", "Tim", 
       "Harriet"}; 
int ages[HOW_MANY]= {22, 24, 106, 6, 18, 32, 24}; 

/* declare your struct for a person here */ 
typedef struct { 
    char *name; 
    int age; 
} person; 

static void insert(person *people[], char *name, int age, int *nextfreeplace) 
{ 
    /* creates memory for struct and points the array element to it. */ 
    people[*nextfreeplace] = malloc(sizeof(person)); 

    /* put name and age into the next free place in the array parameter here */ 
    (*people[*nextfreeplace]).name = name; 
    (*people[*nextfreeplace]).age = age; 

    /* modify nextfreeplace here */ 
    (*nextfreeplace)++; 
} 

int main(int argc, char **argv) 
{ 

    /* declare the people array here */ 
    person *people[HOW_MANY]; 
    int nextfreeplace = 0; 

    for (int i = 0; i < HOW_MANY; i++) 
    { 
    insert (&people, names[i], ages[i], &nextfreeplace); 
    } 

    /* print the people array here*/ 
    for (int i = 0; i < HOW_MANY; i++) { 
    printf("Name: %s. Age: %d\n", (*people[i]).name, (*people[i]).age); 
    } 

    /* Releases the memory allocated by malloc */ 
    for (int i = 0; i < HOW_MANY; i++) { 
    free(people[i]); 
    } 

    return 0; 
} 

它的工作完美,但是當我編譯它時,我得到兩個警告。

arrays.c: In function ‘main’: 
arrays.c:41:13: warning: passing argument 1 of ‘insert’ from incompatible pointer type [-Wincompatible-pointer-types] 
    insert (&people, names[i], ages[i], &nextfreeplace); 
      ^
arrays.c:19:13: note: expected ‘person ** {aka struct <anonymous> **}’ but argument is of type ‘person * (*)[7] {aka struct <anonymous> * (*)[7]}’ 
static void insert(person *people[], char *name, int age, int *nextfreeplace) 

我是新來的,一般的指針和C,想一些幫助解釋爲什麼我得到這些警告和如何擺脫他們。謝謝!

+0

這段代碼有很多問題,但我也不太確定你的意圖。例如,是否需要使用malloc分配堆?如果不是,我會將'people'的定義更改爲在堆棧上進行簡單分配。然而,這使得'insert()'函數幾乎不必要 –

+1

'(* people [* nextfreeplace]).name' - 看起來您正在猜測括號和星號的組合,直到編譯器停止抱怨。這不是學習C的好方法! –

回答

2

TL; DR

使用people而不是&people

龍解釋

這裏是警告消息說:

你的功能insert預計person **類型的參數(一個指針指向person)。你的代碼給它發送一個不同類型的參數:person * (*)[7],這是一個「指向指向person的7個指針的數組的指針」的C方式。

(你可以使用該網站http://cdecl.org地發現:在該領域進入struct person * (*people)[7],它會將其翻譯成英文)

如果你把你的陣列,而不是它的指針,你insert功能,編譯器會將名稱people視爲「指向指向person的指針」,在此上下文中是「指向person的指針數組」的特例。這個過程被稱爲數組到指針的「衰減」,並被解釋爲here

-1

你會得到這些警告,因爲「插入」需要指向人的指針,但只能獲得指向人的指針指針。

在第41行,擺脫 「&」,從 「&人」,像:

插入(人,名字[I],年齡[I],& nextfreeplace);

+0

指向人的指針指向「人***」,並且不會引起混淆。有問題的類型實際上是一個指向數組的指針。 – anatolyg

+0

當從編譯器的角度將一個* x []傳遞給一個函數時,它在堆棧中看到它,它就是一個** x。 –

+0

@AleksiRomanov這是真的,但問題是'&人'不是'** x'或*** ****或類似的東西。 –

1

你也可以這樣做:

/* declare your struct for a person here */ 
typedef struct { 
    char *name; 
    int age; 
} person, *people_t; 

然後

static void insert(people_t people[], char *name, int age, int *nextfreeplace){...} 

然後

people_t people[HOW_MANY]; 

    int nextfreeplace = 0; 

    for (i = 0; i < HOW_MANY; i++){ 
    insert (people, names[i], ages[i], &nextfreeplace); 
    } 

編譯:Visual Studio 2010中

1

這實際上是一條警告,以兩行顯示(第41行的警告源和第19行的引發問題的聲明)。

您可以通過刪除從該呼叫的符號清除警告insert,從而

insert(people, names[i], ages[i], &nextfreeplace); 

在C中,一個陣列的名稱是與它的地址同義。

同時,清理在警告<anonymous>標籤,常見的成語時typedef荷蘭國際集團的結構如下:

typedef struct <name> 
{ 
    ... 
} <name>; 

而你的情況應該是:

typedef struct person { 
    char *name; 
    int age; 
} person; 
+0

「數組的名稱與其地址同義」應該是「在大多數情況下,數組的名稱被轉換爲*第一個元素的地址」。這種轉換不會發生的上下文的一個例子是當與'sizeof'運算符或'&'運算符一起使用時。 –