繁体   English   中英

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

[英]Using pointers when they are elements of a structure array in C

我想检查字符串 SET_NAME 是否是现有集合的名称,如果是,SET1 将指向该集合的地址。

#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;
}

此代码不起作用,可能是由于结构中的元素使用不正确。 编译器这样写给我: Assignment from incompatible pointer type [-Wincompatible-pointer-types] set1 = sets[i].myset; 并且 - 警告:初始化元素在加载时不可计算 [-Wpedantic] {"SETD", &SETD},对于数组中的每个元素。 我正在尝试修复但不明白我的错误在哪里。

  1. 永远不要将 arrays 或指针隐藏在typedef后面
  2. 您的字符串set_name太短。 它必须是 5 个字符长以容纳 null 终止字符
  3. set_name[0] = {'S'}; 没有意义。 如果要将 char 分配给数组的特定元素,请不要使用方括号。
  4. set SETA = {'0'}; 它将使用字符'0'作为第一个元素初始化SETA ,并将 rest 归零。
  5. &SETA的类型错误(指向 16 个字符的数组的指针,而不是指向 char 的指针)

经过一些修改:

#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;
}

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

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]的指针; 这更像是一种风格决定。 这样做的一个优点是编译器可以为您强制执行数组大小检查,尽管另一方面是使用这种技术需要彻底理解 arrays 和指针!


警告initializer element is not computable at load time是指 C89 中的一个限制,该限制已在 C99 中修复,因此您可以通过将编译器设置为 C99 或更高版本来使其消失 go。 在 C89 中, { }初始值设定项的内容必须是常量表达式,例如变量的值,或者不能使用局部变量的地址。

如果您被迫在 C89 模式下编写,那么您可以将初始化程序替换为每个元素的一系列赋值表达式。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM