C 代码编译后从不兼容的指针类型赋值
我最近一直在学习C编程,并编写了一些代码。以下是我编写的代码:C 代码编译后从不兼容的指针类型赋值,c,C,我最近一直在学习C编程,并编写了一些代码。以下是我编写的代码: #include <stdio.h> int main(int argc, char ** argv){ int num[] = {10, 15, 25, 30, 45, 10}; char *names[][11] = {"Drew", "Larry Page", "Seggy", "Mark"}; //int *ip, i = 0; char **ip; int *p,
#include <stdio.h>
int main(int argc, char ** argv){
int num[] = {10, 15, 25, 30, 45, 10};
char *names[][11] = {"Drew", "Larry Page", "Seggy", "Mark"};
//int *ip, i = 0;
char **ip;
int *p, i = 0, j = 0;
for (ip = names; *(ip + i); i++)
printf("%s ", *(ip + i));
printf("\n\n");
for (p = num; j < sizeof(num)/sizeof(num[0]); j++)
printf("%d ", *(p + j));
printf("\n");
return 0;
}
我已经在各种IDE上测试了代码,但得到了类似的警告。感谢您的帮助。问题出在这一行:
char *names[][11] = {"Drew", "Larry Page", "Seggy", "Mark"};
您不需要指向char
的2d指针数组,您需要指向char
的指针数组:
char *names[] = {"Drew", "Larry Page", "Seggy", "Mark"}; /* Don't hardcode 11 */
您需要的是
char*names[11]
字符指针数组,而不是char*names[][11]
宣布它像
char *names[] = {"Drew", "Larry Page", "Seggy", "Mark"};
您收到此警告的原因是
char*names[][11]
属于char*[1][11]
类型,而char**ip
属于char**
类型。
基本上,您所做的是创建指向char的指针的1x11数组(一行11列,11个指针)。
因为C中没有部分初始化,所以前4个指针将指向只读内存中静态字符串文本的地址,其余指针将为零
绕过编译器警告并使代码正常工作的最简单方法是在第一个for循环中强制转换ip=(char**)名称。它将起作用,因为ip
想要指向某个指针的地址,而名称是什么
——它基本上是数组中第一个指针的地址。现在,当您取消引用ip
时,您将获得4个指针,并在标记后停止,因为第五个指针将为0
int main(int argc, char ** argv){
int num[] = {10, 15, 25, 30, 45, 10};
char *names[][11] = {"Drew", "Larry Page", "Seggy", "Mark"};
//int *ip, i = 0;
char **ip;
int *p, i = 0, j = 0;
for (ip = (char** )names; *(ip + i); i++)
printf("%s ", *(ip + i));
printf("\n\n");
for (p = num; j < sizeof(num)/sizeof(num[0]); j++)
printf("%d ", *(p + j));
printf("\n");
return 0;
}
以上两种解决方案都不清楚,我认为它们是“黑客”。我建议您使用下面最后两个示例中的一个。
简要说明:
编译器允许您省略第一个维度大小,因为要计算数组元素的偏移量,您只需要第二个维度大小李>
如果使用-Wall启用警告,编译器通常会发出警告:初始化器周围缺少大括号。所以总是使用大括号,比如Sochar*names[][11]={{{“Drew”,“Larry Page”,“Seggy”,“Mark”}代码>
除了上面的简单解释之外,我假设您希望以某种方式存储字符串数组并打印它们。
有几种方法可以实现这一点:
制作一个指向字符串的指针数组-char*names[]={“Drew”、“Larry Page”、“Seggy”、“Mark”}代码>,但这样就无法更改字符串的内容,因为所有文本字符串都驻留在只读内存中。这就是为什么最好使用const
限定符来更加明确您不能更改内容(const char*names[]={“Drew”、“Larry Page”、“Seggy”、“Mark”};
),如果您不使用它,编译器将允许您更改内容,但当程序执行时,它将生成分段错误,如果您使用const
,编译器甚至不允许您编译
制作一个多维字符串数组-charnames[][11]={{{“Drew”}、{“Larry Page”}、{“Seggy”}、{“Mark”}代码>。在这里,您必须确保知道字符串的大小。您可以在此处更改数组内容
这是修改后的工作版本,没有警告,带有多维数组:
int main(int argc, char ** argv){
int num[] = {10, 15, 25, 30, 45, 10};
char names[][11] = {{"Drew"}, {"Larry Page"}, {"Seggy"}, {"Mark"}};
//int *ip, i = 0;
char (*ip)[11];
int *p, i = 0, j = 0;
for (ip = names; i < sizeof(names)/sizeof(names[0]); i++)
printf("%s ", *(ip + i));
printf("\n\n");
for (p = num; j < sizeof(num)/sizeof(num[0]); j++)
printf("%d ", *(p + j));
printf("\n");
return 0;
}
int main(int argc,char**argv){
int num[]={10,15,25,30,45,10};
字符名[][11]={{“Drew”}、{“Larry Page”}、{“Seggy”}、{“Mark”};
//int*ip,i=0;
字符(*ip)[11];
int*p,i=0,j=0;
对于(ip=名称;i
以下是带字符串指针数组的修改版本:
int main(int argc, char ** argv){
int num[] = {10, 15, 25, 30, 45, 10};
char *names[11] = {"Drew", "Larry Page", "Seggy", "Mark"};
//int *ip, i = 0;
char **ip;
int *p, i = 0, j = 0;
for (ip = names; *(ip + i); i++)
printf("%s ", *(ip + i));
printf("\n\n");
for (p = num; j < sizeof(num)/sizeof(num[0]); j++)
printf("%d ", *(p + j));
printf("\n");
return 0;
}
int main(int argc,char**argv){
int num[]={10,15,25,30,45,10};
char*names[11]={“Drew”、“Larry Page”、“Seggy”、“Mark”};
//int*ip,i=0;
字符**ip;
int*p,i=0,j=0;
对于(ip=名称;*(ip+i);i++)
printf(“%s”,*(ip+i));
printf(“\n\n”);
对于(p=num;j
我已尝试修改您的代码。进一步的优化仍有可能。感谢@keine的快速回复。如果没有11,我会得到这个分段错误:bash:line 1:7分段错误(内核转储)bash-c'gcc-o jdoodle*.c&&./jdoodle'
@Fokwa最佳检查循环condition@FokwaBest:NULL
-终止指针数组:char*names[]={“Drew”、“Larry Page”、“Seggy”、“Mark”、NULL}代码>大家好。我将for循环更新为for(ip=names;I
,错误消失了。谢谢大家。下次使用-Wall-Wextra
编译时,您会看到更多的东西也可以用C来处理,而不是*(ip+i)
我们编写ip[i]
;-)谢谢你的详细解释。对于第二个示例,我们可以省略大小,因为我们在声明时正在初始化数组char*names[]
然后在for循环中使用i
可以忽略大小,但我没有忽略它,因为我试图修改您的代码。请注意,您的代码保持不变,只更正其中不正确的部分。无需更改for循环条件,因为C中没有部分初始化,名称
将在标记
字符串后填充空指针,因此for循环将按预期终止。我已经测试了所有示例,它们按预期工作。
int main(int argc, char ** argv){
int num[] = {10, 15, 25, 30, 45, 10};
char names[][11] = {{"Drew"}, {"Larry Page"}, {"Seggy"}, {"Mark"}};
//int *ip, i = 0;
char (*ip)[11];
int *p, i = 0, j = 0;
for (ip = names; i < sizeof(names)/sizeof(names[0]); i++)
printf("%s ", *(ip + i));
printf("\n\n");
for (p = num; j < sizeof(num)/sizeof(num[0]); j++)
printf("%d ", *(p + j));
printf("\n");
return 0;
}
int main(int argc, char ** argv){
int num[] = {10, 15, 25, 30, 45, 10};
char *names[11] = {"Drew", "Larry Page", "Seggy", "Mark"};
//int *ip, i = 0;
char **ip;
int *p, i = 0, j = 0;
for (ip = names; *(ip + i); i++)
printf("%s ", *(ip + i));
printf("\n\n");
for (p = num; j < sizeof(num)/sizeof(num[0]); j++)
printf("%d ", *(p + j));
printf("\n");
return 0;
}