当指针是C a中结构数组的元素时使用指针

k5hmc34c  于 2023-01-08  发布在  其他
关注(0)|答案(2)|浏览(171)

我想检查字符串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}。我正在尝试修复,但不知道错误在哪里。

w8f9ii69

w8f9ii691#

对原始代码的最小修复是:

typedef char set[16];    // instead of "unsigned char"

以及

set1 = *sets[i].myset;   // added the "*" operator

因为sets[i].myset是指向char[16]的指针,所以应用*运算符会得到一个char[16],然后你可以让set1指向它的衰减。
另一个答案隐含地建议重新设计代码,完全不使用指向char[16]的指针;这更多的是一个风格上的决定。这样做的一个好处是编译器可以为你强制数组大小检查,尽管另一方面是使用这种技术需要彻底理解数组和指针!
警告initializer element is not computable at load time指的是C89中的一个限制,这个限制在C99中已经被修复了,所以你可以通过将编译器设置为C99或更高的模式来消除它。在C89中,{ }初始化器的内容必须是常量表达式,例如变量的值,或者局部变量的地址不能被使用。
如果你被强制在C89模式下写,那么你可以用一系列赋值表达式来代替初始化器。

ngynwnxp

ngynwnxp2#

1.永远不要在typedef后面隐藏数组或指针
1.您的字符串set_name太短。它的长度必须为5个字符才能容纳空终止字符

  1. set_name[0] = {'S'};没有意义,如果你想给数组的特定元素赋一个字符,不要使用括号。
  2. set SETA = {'0'};,它将以字符'0'作为第一元素来初始化SETA,并将其余的归零。
  3. &SETA的类型错误(指向16个字符的数组的指针,而不是指向字符的指针)
    经过一些修改后:
#define SETLENGTH 16

int main(){

    char set_name[] = "SETB";
    char *set1;
    int i;

    char SETA[SETLENGTH] = "";
    char SETB[SETLENGTH] = "";    
    char SETC[SETLENGTH] = "";    
    char SETD[SETLENGTH] = "";    

    struct{
        char *name;
        char *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;
}

相关问题