如果您的代码在没有警告的情况下编译,则说明您没有充分利用您的编译器。如果您要求它这样做,它将对您有所帮助。了解如何让它在编译时出现警告,并了解如何修复它诊断出的问题。我使用以下命令中的一个或另一个编译了以下代码:
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);
}
}
这是具有 64 位编译的 Mac OS X 10.7.4 机器的输出:
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
当您了解各种数字是如何得出的时,您就会很好地理解事物。
注意&array[1]
被解释为&(array[1])
; 它与(&array)[1]
类型和大小不同。数组下标等后缀运算符比地址 ( &
) 和间接 ( *
) 运算符等一元运算符绑定得更紧密。