我正在学习 learn-c.org 上的教程。来到关于Arrays 和 Pointers的部分,如果我在我的系统上运行示例程序的前两行会发出警告:
char vowels[] = {'A', 'E', 'I', 'O', 'U'};
char *pvowels = &vowels;
Run Code Online (Sandbox Code Playgroud)
代码运行,但我收到以下警告:
警告:从不兼容的指针类型 'char (*)[5]' 初始化 'char *' [-Wincompatible-pointer-types] 15 | char *pvowels = &vowels;
如果我将其转换为
char *pvowels = (char *) &vowels;
Run Code Online (Sandbox Code Playgroud)
但这是处理该警告的正确方法吗?它似乎没有必要摆在首位,我真的不明白之间的差别char *
和char (*)
。
接下来,该printf
行对第三个参数发出警告,说:
警告:格式 '%u' 需要类型为 'unsigned int' 的参数,但参数 3 的类型为 'char *' [-Wformat=]
(参数 5 和 7 相同)
这个我什至不知道如何投射以绕过警告......打印这个的正确方法是什么?
char vowels[] = {'A', 'E', 'I', 'O', 'U'};
char *pvowels = &vowels;
int i;
// Print the addresses
for (i = 0; i < 5; i++) {
printf("&vowels[%d]: %u, pvowels + %d: %u, vowels + %d: %u\n", i, &vowels[i], i, pvowels + i, i, vowels + i);
}
// Print the values
for (i = 0; i < 5; i++) {
printf("vowels[%d]: %c, *(pvowels + %d): %c, *(vowels + %d): %c\n", i, vowels[i], i, *(pvowels + i), i, *(vowels + i));
}
Run Code Online (Sandbox Code Playgroud)
随着&vowels
你得到一个指向数组本身的指针,它是char (*)[5]
错误消息中提到的类型。你似乎想要的是一个指向数组中第一个元素的指针,它应该是&vowels[0]
,或者简单的,vowels
因为它衰减到指向它的第一个元素的指针:
char *pvowels = vowels;
Run Code Online (Sandbox Code Playgroud)
此外,当您想打印指针时,printf
您需要使用%p
格式。并且它打印 type 的“通用”指针void *
,因此要完全正确,您需要将所有指针强制转换为void *
printf("&vowels[%d]: %p, pvowels + %d: %p, vowels + %d: %p\n", i, (void *) &vowels[i], i, (void *) (pvowels + i), i, (void *) (vowels + i));
Run Code Online (Sandbox Code Playgroud)