2012-02-19 124 views
10

我是C的新手,C語言的內容與我學過的其他語言不同。在我的作業中,我想創建一個指向字符數組的chars數組,但不是創建一個多維char數組,而是讓我有更多的控制權並創建char數組,並將每個數組放入原始字符陣列:我可以在C中創建一個Char指針數組嗎?

char keywords[10]; 
keywords[0] = "float"; 

上面的例子是澄清和一個簡單的情況。但我的問題是由於我一直在做的研究,我對某些事情感到困惑。通常這會在其他語言的工作,但在C這將是:

char *keyword[10]; 
keywords[0] = "float"; 

但是,當我想通過一個函數來發送,爲什麼這是必要的:

void function(char **keyword); //function prototype 

難道只是路過數組指針就夠了?

+3

你認爲/期望函數原型應該是什麼? – 2012-02-19 19:43:05

+0

你也可以通過char *關鍵字[],意思是完全一樣的東西 – Matthieu 2012-02-19 19:44:38

+0

是的,你可以......做你想做的事。但真正的問題是你有什麼好的C編程書籍閱讀...... – 2012-02-19 19:44:42

回答

10

它看起來像你通過雙星在

void function(char ** keyword); 

混淆了雙星只是意味着這個函數需要您傳遞指針的指針爲char。此語法不包含有關您使用數組的事實的任何信息,或者該字符實際上是字符串中許多字符的第一個字符。程序員可以知道char **實際指向的是什麼樣的數據結構。

例如,假設您的數組的開頭存儲在地址0x1000。該函數的keyword參數應具有值0x1000。如果取消引用keyword,則會獲得數組中的第一個條目,即char *,該條目指向字符串「float」中的第一個字符。如果你解引用char *,你會得到char「f」。

該的(設計的)代碼將如下所示:

void function(char **keyword) 
{ 
    char * first_string = *keyword; // *keyword is equivalent to keyword[0] 
    char first_char = *first_string; // *first_string is equivalent to first_string[0] 
} 

有在上面的例子中的兩個指針。通過在解引用它之前向第一個指針添加偏移量,可以訪問數組中的不同字符串。在解引用它之前,通過向第二個指針添加偏移量,可以訪問字符串中的不同字符。

+0

我明白你在說什麼。它與星星有點混淆,但我很欣賞澄清。 – Andy 2012-02-19 20:44:51

+0

向類型T添加星號只是將其更改爲「指向T」。所以「char *」是「指向char的指針」,「char **」是「指向char的指針指針」。 – 2012-02-19 23:27:08

1
char *keyword[10]; 

keywordchar *的數組10。在一個值上下文中,它轉換爲一個指向char *的指針。

這種轉換是什麼克里斯托雷克稱「治國」部分:

「作爲別處指出,C大約有數組和指針非常重要的策略,這條 - 規則 - - 在數值上下文中,'T數組'類型的對象變成'T指針'類型的值,指向該數組的第一個元素「

查看此處獲取更多信息: http://web.torek.net/torek/c/pa.html

的C-FAQ也有這個陣列上的指針轉換的條目:

問6.3:那麼,什麼是由「用C指針和數組'的等價是什麼意思?

http://c-faq.com/aryptr/aryptrequiv.html

+2

這是正確的,但對於不熟悉該語言的人來說不是很清楚。你應該考慮解釋你的意思是「價值背景」。 – 2012-02-19 19:45:08

+0

我明白鏈接 – Andy 2012-02-19 20:38:19

0

在C中,你不能真正傳遞數組給一個函數。相反,你傳遞一個指向數組的開始的指針。由於您有char*的數組,因此該函數將獲得指向char*的指針,即char**

如果你想,你可以寫(在原型)char *keyword[]而不是char **keyword。編譯器會自動轉換它。

此外,在C中,您可以像數組一樣取消引用指針,所以您幾乎沒有任何操作「轉換爲指針」。

1

如果你想

void function(char **keyword); 

安迪,想想一個數組只是一個指針(到數組的開頭),這就是爲什麼你寫的:

void function(char **keyword); 

因爲你有爲char指針創建一個數組。

如果是比較容易理解嘗試:

void function(char *keyword[]); 

但它使用的第一個多C標準,但如果你使用C++編譯器不會真正的問題。

+4

對於「數組只是一個指針」的義務-1。 – 2012-02-19 20:00:56

1

下面是答案。

#include<stdio.h> 

int main(void) 
{ 
     char *CharPtr[3]; 
     char a[4]="abc"; 
     char b[4]="def"; 
     char c[4]="ghi"; 
     CharPtr[0]=a; 
     CharPtr[1]=b; 
     CharPtr[2]=c; 

     printf("\n content of CharPtr[0] =%s",CharPtr[0]); 
     printf("\n content of CharPtr[1] =%s",CharPtr[1]); 
     printf("\n content of CharPtr[2] =%s\n",CharPtr[2]); 

     printf(" \n content of char a[4]=%s",a); 
     printf(" \n content of char b[4]=%s",b); 
     printf(" \n content of char c[4]=%s\n",c); 
} 
+0

這不完全是在問題中提出的問題......我想你應該先仔細閱讀問題.... – Mayank 2014-07-10 10:22:28

0

char *keywords[10]是一個字符指針數組。所以keywords[0],keywords[1] ..等都將地址分配給不同的字符數組。

printf可以使用%skeywords[0]打印整個字符數組,其地址(即陣列中的第一個字節的地址)存儲在keywords[0]

雖然傳遞給一個函數,如果你給​​,你指的是在(存儲在地址keywords[0]),這是再一次一個地址值。所以,要獲得價值而不是地址,你可以添加另一個* ......希望澄清一下..

0

我假設要分配的第一串:以關鍵字的第一個索引位置

"float" 

[0]

char keyword[0] = "float"; 

其是陣列的第一索引的位置:

char keyword[10]; 

如果以前是這種情況,那麼從某種意義上說,您基本上是在創建一個數據結構擁有一個數據結構。任何類型的數組都是C中該類型的'最小'數據結構。考慮到在你的例子中你正在創建一個字符數組,那麼你實際上正在使用最小的數據類型(char = 1bit)最小的內置數據結構(數組)。

這樣說,如果在你的例子中,你正在嘗試創建一個數組數組;你的字符排列

/* Hold ten characters total */ 
char keyword[10]; 

被設計成可容納10個字符。每個索引位置一個(你可能已經知道)。所以聲明陣列標題關鍵字後,然後嘗試初始化所述陣列的所述第一索引位置與另一(第二個)的字符數組:

/* I believe this is what you had stated */ 
char keywords[0] = "float"; 

利用具有在大小爲5點的位置的索引的第二個字符陣列。

爲了達到你想要的目標,你基本上會創建一個數組,它基本上模擬了一個「保存」其他數據結構的數據結構的效果。

注意:如果您有/試圖創建一個數據結構來保存包含數據結構的數據結構。又名一個三重嵌套數據結構,在這種情況下,我認爲這將是一個矩陣,我不建議!

無論如何,矩陣結構將以關鍵字的第一個索引位置的形式,被分配了整個關鍵字數組,其中包括存儲在關鍵字數組的每個索引位置的所有數據。然後會有一些可能想:keywords1,keywords2,... keywords9,

這將基本上模仿的形式:

char *keyword[10] = { 
         char *keywords0[10] = {"float", etc, etc, etc.}; 
         char *keywords1[10] = {"keyword1", "secondIndexOfThisArray", etc, etc, etc.}; 
         and so 

        }; 

所以基本上由右至左,關鍵字陣列,是一個數組指向指向字符數組的指針數組的指針。

如果這就是你所代表的,你會更好地定義一個自定義數據類型的結構/記錄,並在該自定義結構中,你會想要定義從屬或子級別的結構。你也可以預先聲明它們然後初始化它們。

例如

typedef *nestedDataStructures { 

    struct keyWords[]; 
    struct keyWords1[]; 
    struct keyWords2[]; 

    ... and so on. 
}; nestedDataStructures 

反而添十層結構,以一個自定義的結構,我會分解爲3或4(怎麼過許多結構和使用),並以產生抽象的對稱層創建一個模塊,你操縱你的數據集。

無論如何,您不能創建字符數組並且可能以您所做的方式(或者誰知道也可以)分配另一個字符數組,但您希望模擬包含數組的數組的方式,就是先在X數字索引位置上創建一個字符指針數組,然後初始化,然後在原始聲明的初始化中以字符串的形式使用字符數組。

所以基本上你可以預先聲明你的整個數組,然後在你的程序設計中,取消引用每個索引位置,使用賦值,或者打印/寫入索引位置。

例如像你總是可以做這樣的事情:

/* Example of the program and declaration with out a function */ 
#include <stdio.h> 

int main(){ 

    /* 
    * A character pointer array that contains multiple 
    * character arrays. 
    */ 

    char *grewMe[2] = {"I want to ", "grow to be bigger"}; 

    int w = 0; 

    for(; w < 2;) { 
     printf("%s", grewMe[w]); 
     ++w; 
    } 

    printf(" :-)\n"); 
    w = 0; 
    return 0; 
} 
// Output: 
// I want to grow to be bigger :-) 

或者是這樣的:

/* Example of program: function passed arguments 
* of a pointer to the array of pointers 
*/ 
#include <stdio.h> 

void mygrowth(char *growMe[]); 

int main(){ 

    char *growMe[2] = {"I want to ", "grow to be bigger"}; 

    mygrowth(growMe); 
    printf(" :-)\n"); 

    return 0; 

} 
void mygrowth(char *growMe[]) 
{ 

    int w = 0; 
    for (; w < 2;) { 
     printf("%s", growMe[w]); 
     ++w; 
    } 
} 

每個索引位置的分配,因爲它是作爲參數傳遞:

/* 
* This program compiles, runs and outputs properly 
* Example of a program with a function of 
* arguments pnt2pnter 
*/ 

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

void thoughtAsAFunction(char **iThink); 

int main() 
{ 

    char *iThink[10] = {"I am trying to grow, but it's a hard task to ", 
         "accomplish. My father is short ", 
         "my mother is even shorter than him, ", 
         "what is the probability of me getting taller? ", 
         "Well both my grandfather's were Six ", 
         "Foot Five, and both my grandmother's ", 
         "were over 5 foot 8 inches tall! If my ", 
         "grandparent's genes point to my parents, and my ", 
         "parent's genes point to mine I might have a chance ", 
         "of being 6 foot. Do you know what I mean? "}; 

    thoughtAsAFunction(iThink); 

    printf(":-)\n"); 

    return 0; 
} 
void thoughtAsAFunction(char **iThink) { 

    int andy = 0; 
    for (; andy < 10;) { 
     char * pntThroughPnt = iThink[andy]; 
     printf("%s", pntThroughPnt); 
     ++andy; 
    } 
    andy = 0; 
} 

或通過引用,以循環計數變量的增量:

/* 
* This program compiles, runs, and outputs all of the character 
* arrays. 
* 
*/ 
#include <stdio.h> 
#include <stdlib.h> 

void thoughtAsAFunction(char **iThink); 

int main() 
{ 

    char *iThink[10] = {"I am trying to grow, but it's a hard task to ", 
         "accomplish. My father is short ", 
         "my mother is even shorter than him, ", 
         "what is the probability of me getting taller? ", 
         "Well both my grandfather's were Six ", 
         "Foot Five, and both my grandmother's ", 
         "were over 5 foot 8 inches tall! If my ", 
         "grandparent's genes point to my parents, and my ", 
         "parent's genes point to mine, then I might have a chance ", 
         "of being 6 foot. Do you know what I mean? "}; 

    int andy = 0; 
    for (; andy < 10;) { 
     // pass by reference and increment. 
     thoughtAsAFunction(&iThink[andy]); 
     ++andy; 

    } 

    printf(":-)\n"); 
    andy = 0; 

    return 0; 
} 
void thoughtAsAFunction(char **iThink) { 

    char * pntThroughPnt = *iThink; 
    printf("%s", pntThroughPnt); 

} 

請記住,如果您聲明指針數組(char * array [10];),並且每個指針都指向一個字符數組,則是這種情況。

相關問題