char (*p)[]是定義一個指向char型數組的指針.
char p[]是定義一個數組,p也是指針,只不過是常量.對吧?
#include <stdio.h>
int main()
{
char (*p)[10] ;
char a[10];
p=a;
}
為什麼提示
[root@localhost ~]# cc test.c
test.c: 在函數 ‘main’ 中:
test.c:6: 警告:從不兼容的指針類型賦值呢?
你把p=a 改成 p=&a就可以了。
這是c語言迷惑人的地方。很多書都告訴大家數組名就是數組的地址,但其實它是的數組第一個元素的地址,類型是char *。而&a 表示的才是數組的地址,類型是char (*)[10]。由於數組的地址在值上面和數組第一個元素地址的值是相同的,所以大家平時就認為&a和a是一樣的,產生了誤會。
所以,p=a的警告在於你把一個char型的地址賦給了一個char (*)[10]的指針。當然,這樣做的結果沒錯,不過多了個警告。
發表於: 2006-10-13 12:37 主題: [引用] [投訴] [快速回復]
--------------------------------------------------------------------------------
指向數組的指針 和 指針數組是不一樣的
指向數組的指針char (*p)[10]表示p指的是一個數組,p+1與p的差距是sizeof(char [10]),是移動指到另一個數組,這裡sizeof(p)在32位機器上應該是4,指針的長度是4
指針數組char *p[10],表示的是一個數組,數組中每個元素都是指針,這裡sizeof(p)在32位機器上應該是40,=10 * sizeof(char*),這兒是數組的長度,而不是指針的長度,也說明他是個數組,跟指向指針的指針(char **p)也是不一樣的
還不明白自己去看書了,不回復了
好像大家說得挺復雜的,這個問題,其實可以歸納為三個問題:
1、p是什麼?
2、a是什麼?
3、&a又是什麼?
先看這個例子:
int *p;
int a[10];
p = a;
這裡,p = a ,其實僅僅是指向了數組的下標為0的元素,它僅代表一個元素,而不是整個數組,你不能用指針p來描述整個a[10],除非你做一個循環。
好了,把最後一句 p = a改為:
p = &a;
p 僅僅是代表一個元素,而&a是整個數組的地址(&a實際上是指向數組a的指針),一個元素是不能指向整個數組的,因為它們類型不一致,編譯器會警告!!!
(令人疑惑的是:雖然是警告,但又可以編譯運行,這是因為&a使終表示一個地址,如0x0012ff70,而&a[0]也是一個地址,p = &a[0],那當然……,雖然可以運行,但是從類型上來講,這樣是不對的)
說了一大堆和樓主問題不相干的。其實好像已經回答了這個地址,樓主的程序中:
p是一個指針,是一個指向有10元素的數組的指針,——它已經代表了10個元素,不再代表一個元素了!!!
a,前面已經說了,a是下標為0的元素的地址——它僅代表了&a[0]
大家好像不在一個數量級別上吧?編譯器當然要警告你,當然你也可以強行這麼用,原因如前所述。
所以,要讓大家在一個級別上,很簡單,把最後一句
p = a;
改成
p = &a;
搞定!!!
後記:雖然a[10]中,a和&a,表示的絕對的地址的二進制數是相同的,比如0x001270FF,但是,它們代表的含義卻不是一樣的!!!
我舉例用了int來代替樓主的char類型,主要是因為char常常讓我們迷惑……之所以迷惑,是因為我們習慣於
char *p;
char a[10];
p=a;
/*以下把p看成一個字符串來用*/
事實上,C是沒有字符串的類型的,p 之所以能看成字符串,因為p指向了第一個元素,我們可以使用它,直至'\0'
Over!
不對之處還請諒解!
兩個指針級別都不一致,一個是char (*)[10], 一個是char [10],當然要警告你一下
char [10] 是數組 a 的定義類型,是數組類型,而不是指針類型。數組可以轉換為指針,所以一個數組到底是作為數組類型還是指針類型使用取決於它所處的上下文環境。程序中的 p = a; 中 a 作為指針使用,此時它的類型是 char*。
>>(char p[] 中,)你這個p怎麼能++的哦,這個p就是個常量,不是左值,不能對其進行賦值什麼的操作
>> a是指針常量,不能作為左值,當然也是不能自增的了..
首先可以肯定的是:樓主程序中的數組 a 是一個非靜態數組,所以 a 不是一個常量。
經常看到上面的這種錯誤的觀點,即把改變數組名 a 的操作(如對其賦值、自加等)是非法的原因歸結於“數組名是常量”。我在下面的帖子中對此進行了澄清:
http://bbs.chinaunix.net/viewthr ... p;extra=&page=2
按照標准的說法,數組名 a 不能被改變是因為數組對象是一個“不能被改變的左值”。這句話表達了兩個意思:一是數組對象是一個左值,二是不存在數組類型的賦值、自加、自減等操作。另外,數組對象 a 作為指針使用的時候,你可以說它是一個常量指針(這總是正確的),然而能否說成是一個指針常量(即地址常量)就又另當別論了(具體參見上面給出的帖子中的內容)。
>> 不過a裡面存的不已經是數組第零個元素的地址,怎麼還能&取址呢?
因為這個地址值是“轉換”而來的,而不是存放在變量 a 中,這是數組類型一個比較特殊的地方。另外,能對數組 a 進行取址運算是因為 a 表示數組對象的時候是一個左值。
>> 難道&a和a內容一樣,差別在於類型變了,一個是單個元素的指針,一個是數組的指針了麼?
&a 和作為指針使用的 a 這兩個表達式都只有“值”的概念,不代表任何對象,所以沒有你所認為的“內容”。它們的值僅僅是在數值上相等(因為指向位置相同),然而指針類型不同:前者是 char(*)[10],後者是 char*。
#include <stdio.h>
int main()
{
char (*p)[10] ;
char a[10];
p=a; // First of all, "a" means &a[0], p should be assigned with the address of an array, not the address of the array element.
You should write as : p = &a;
}
/*----------------------------
看後寫出如下程序,正確得到結果
----------------------------*/
#include <stdio.h>
#include <string.h>
int main()
{
char (*p)[10] ;
char a[10];
strcpy(a,"hello,world");
p=&a;
printf("p=%s\n "
"the second char in p is %c\n",*p,(*p)[1]);
return 0;
}