我想检查字符串SET_NAME是否是现有集合的名称,如果是,SET 1将指向该集合的地址。
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
typedef unsigned char set[16];
int main(){
char set_name[5] = {'0'};
char *set1;
int i;
set_name[0] = 'S';
set_name[1] = 'E';
set_name[2] = 'T';
set_name[3] = 'B';
set SETA = {'0'};
set SETB = {'0'};
set SETC = {'0'};
set SETD = {'0'};
struct{
char *name;
set *myset;
}sets[]={
{"SETA", &SETA},
{"SETB", &SETB},
{"SETC", &SETC},
{"SETD", &SETD}
};
for(i=0; i < 4;i++){
if(strcmp(set_name, sets[i].name)==0){
set1 = sets[i].myset;
printf("the set is found!\n%s\n", set_name);
}
}
return 0;
}
这段代码不起作用,可能是因为结构中的元素使用不正确。编译器这样写给我:从不兼容的指针类型赋值[-Wincompatible-pointer-types] set 1 = sets[i].myset;以及-警告:对于数组中的每个元素,初始化器元素在加载时不可计算[-Wpedantic] {“SETD”,&SETD}。我正在尝试修复,但不知道错误在哪里。
2条答案
按热度按时间w8f9ii691#
对原始代码的最小修复是:
以及
因为
sets[i].myset
是指向char[16]
的指针,所以应用*
运算符会得到一个char[16]
,然后你可以让set1
指向它的衰减。另一个答案隐含地建议重新设计代码,完全不使用指向
char[16]
的指针;这更多的是一个风格上的决定。这样做的一个好处是编译器可以为你强制数组大小检查,尽管另一方面是使用这种技术需要彻底理解数组和指针!警告
initializer element is not computable at load time
指的是C89中的一个限制,这个限制在C99中已经被修复了,所以你可以通过将编译器设置为C99或更高的模式来消除它。在C89中,{ }
初始化器的内容必须是常量表达式,例如变量的值,或者局部变量的地址不能被使用。如果你被强制在C89模式下写,那么你可以用一系列赋值表达式来代替初始化器。
ngynwnxp2#
1.永远不要在
typedef
后面隐藏数组或指针1.您的字符串
set_name
太短。它的长度必须为5个字符才能容纳空终止字符set_name[0] = {'S'};
没有意义,如果你想给数组的特定元素赋一个字符,不要使用括号。set SETA = {'0'};
,它将以字符'0'
作为第一元素来初始化SETA
,并将其余的归零。&SETA
的类型错误(指向16个字符的数组的指针,而不是指向字符的指针)经过一些修改后: