如果您的代碼編譯時沒有警告,那麼您沒有充分利用您的編譯器。它會幫助你,如果你問它這樣做。學習如何使用警告進行編譯,並學習如何解決它所診斷的問題。我編譯下面的代碼與一個或另一個這些命令:
gcc -O3 -g -std=c99 -Wall -Wextra -m64 array-stuff.c -o array-stuff
gcc -O3 -g -std=c99 -Wall -Wextra -m32 array-stuff.c -o array-stuff
這對乾淨的代碼與GCC一個很好的起點。的確,-Wall
沒有-Wextra
也不錯。
這裏是你的代碼的改編(在文件array-stuff.c
) - 雖然大部分是不同的:
#include <stdio.h>
#include <inttypes.h>
int main(void)
{
// DC4M = Doesn't compile for me, because I compile with stringent warnings
char ar[16] = { 'a', 'b', 'c', '\0' }; // Note explicit size
printf("%-18s %s\n", "Code:", "char ar[16] = { 'a', 'b', 'c', '\0' };");
//printf("argument: &ar %s\n", &ar); // DC4M
printf("argument: &ar[1] %s\n", &ar[1]);
printf("%-18s 0x%" PRIXPTR "\n", "ar:", (uintptr_t)ar);
printf("%-18s 0x%" PRIXPTR "\n", "&ar:", (uintptr_t)&ar);
printf("%-18s 0x%" PRIXPTR "\n", "(ar+1):", (uintptr_t)(ar+1));
printf("%-18s 0x%" PRIXPTR "\n", "(&ar+1):", (uintptr_t)(&ar+1));
printf("%-18s 0x%" PRIXPTR "\n", "&ar[1]:", (uintptr_t)(&ar[1]));
printf("%-18s 0x%" PRIXPTR "\n", "&(ar[1]):", (uintptr_t)(&(ar[1])));
printf("%-18s 0x%" PRIXPTR "\n", "(&ar)[1]:", (uintptr_t)((&ar)[1]));
printf("%-18s %zu\n", "sizeof(ar):", sizeof(ar));
printf("%-18s %zu\n", "sizeof(&ar):", sizeof(&ar));
printf("%-18s %zu\n", "sizeof(void*):", sizeof(void*));
printf("%-18s %zu\n", "sizeof(ar[1]):", sizeof(ar[1]));
printf("%-18s %zu\n", "sizeof(&ar[1]):", sizeof(&ar[1]));
printf("%-18s %zu\n", "sizeof(&(ar[1])):", sizeof(&(ar[1])));
printf("%-18s %zu\n", "sizeof((&ar)[1]):", sizeof((&ar)[1]));
{
char a = 's';
char *pa = &a;
printf("%-18s %s\n", "Code:", "char a = 's';");
printf("%-18s %s\n", "Code:", "char *pa = &a;");
//printf("argument: &pa %c\n", &pa); // DC4M
printf("%-18s 0x%" PRIXPTR "\n", "&pa:", (uintptr_t)&pa);
printf("%-18s 0x%" PRIXPTR "\n", "&a:", (uintptr_t)&a);
printf("%-18s 0x%" PRIXPTR "\n", "pa:", (uintptr_t)pa);
}
{
char *pa = &ar[0];
char **ppa = &pa;
//printf("argument: &pa %s\n", ppa); // DC4M
printf("%-18s %s\n", "Code:", "char *pa = &ar[0];");
printf("%-18s %s\n", "Code:", "char **ppa = &pa;");
printf("%-18s 0x%" PRIXPTR "\n", "&pa:", (uintptr_t)&pa);
printf("%-18s 0x%" PRIXPTR "\n", "ppa:", (uintptr_t)ppa);
printf("%-18s 0x%" PRIXPTR "\n", "*ppa:", (uintptr_t)*ppa);
printf("%-18s 0x%" PRIXPTR "\n", "&ppa:", (uintptr_t)&ppa);
}
}
這是從Mac OS X 10.7.4機的輸出與一個64位編譯:
Code: char ar[16] = { 'a', 'b', 'c', '
argument: &ar[1] bc
ar: 0x7FFF6C9DE570
&ar: 0x7FFF6C9DE570
(ar+1): 0x7FFF6C9DE571
(&ar+1): 0x7FFF6C9DE580
&ar[1]: 0x7FFF6C9DE571
&(ar[1]): 0x7FFF6C9DE571
(&ar)[1]: 0x7FFF6C9DE580
sizeof(ar): 16
sizeof(&ar): 8
sizeof(void*): 8
sizeof(ar[1]): 1
sizeof(&ar[1]): 8
sizeof(&(ar[1])): 8
sizeof((&ar)[1]): 16
Code: char a = 's';
Code: char *pa = &a;
&pa: 0x7FFF6C9DE560
&a: 0x7FFF6C9DE56F
pa: 0x7FFF6C9DE56F
Code: char *pa = &ar[0];
Code: char **ppa = &pa;
&pa: 0x7FFF6C9DE558
ppa: 0x7FFF6C9DE558
*ppa: 0x7FFF6C9DE570
&ppa: 0x7FFF6C9DE550
這是從32位編譯的輸出:
Code: char ar[16] = { 'a', 'b', 'c', '
argument: &ar[1] bc
ar: 0xC008A670
&ar: 0xC008A670
(ar+1): 0xC008A671
(&ar+1): 0xC008A680
&ar[1]: 0xC008A671
&(ar[1]): 0xC008A671
(&ar)[1]: 0xC008A680
sizeof(ar): 16
sizeof(&ar): 4
sizeof(void*): 4
sizeof(ar[1]): 1
sizeof(&ar[1]): 4
sizeof(&(ar[1])): 4
sizeof((&ar)[1]): 16
Code: char a = 's';
Code: char *pa = &a;
&pa: 0xC008A668
&a: 0xC008A66F
pa: 0xC008A66F
Code: char *pa = &ar[0];
Code: char **ppa = &pa;
&pa: 0xC008A664
ppa: 0xC008A664
*ppa: 0xC008A670
&ppa: 0xC008A660
W¯¯如果你明白各種數字是如何得出的,你就會很好地理解事物。
請注意,&array[1]
被解釋爲&(array[1])
;它不同於(&array)[1]
的類型和大小。後綴運算符(如數組下標)比一元運算符(如地址(&
)和間接運算符(*
))的綁定更緊密。
數組不是指針,如果這就是你所暗示的'它本身是指向第一個元素指針的指針'。 – chris 2012-07-19 02:07:10
僅供參考:您可以通過突出顯示並單擊「{}」按鈕來格式化代碼。你不需要'
':) :) – Blorgbeard 2012-07-19 02:17:22
@EthOmus - 問問你自己,如果一個指針和一個數組*是完全相同的東西,那麼任何人都會在乎將它們添加到語言中嗎? – 2012-07-19 10:56:00