我想将一个相同的结构复制到另一个结构中,然后将其用作第一个结构的比较.问题是,当我这样做时,我的编译器给了我一个警告!我应该以其他方式做到这一点还是我做错了:
在标题文件中:
extern struct RTCclk
{
uint8_t second;
uint8_t minute;
uint8_t hour;
uint8_t mday;
uint8_t month;
uint8_t year;
}
RTCclk;
Run Code Online (Sandbox Code Playgroud)
在C文件中:
struct RTCclk RTCclk;
struct RTCclk RTCclkBuffert;
void FunctionDO(void)
{
... // Some Code
/* Copy first struct values into the second one */
memcpy(&RTCclk, &RTCclkBuffert, sizeof RTCclk);
}
Run Code Online (Sandbox Code Playgroud) 我正在尝试测试是否已经设置了属性.我知道有了我得到的物品:
CGRect ppGoalFrame;
LocalPlaySetup *localPlaySetup;
Run Code Online (Sandbox Code Playgroud)
我可以测试一下
if (localPlaySetup == nil)
Run Code Online (Sandbox Code Playgroud)
但如果我尝试使用== nil或== NULL测试CGRect
if (ppGoalFrame == nil)
Run Code Online (Sandbox Code Playgroud)
我明白了
invalid operands to binary == (have 'CGRect' and 'void *')
Run Code Online (Sandbox Code Playgroud)
那么CGRect"无效",无效,无......?在它设定之前?显然我无法将CGrect与void指针进行比较(我不能使用ppGoalFrame == void); 还有另一种测试方法吗?到目前为止Objective-C很容易理解,但是一旦C出现,我就会有点迷失.
我的意思是,struct sockaddr当我检查两个是否struct sockaddr有相同的IP地址和端口号时,我应该比较哪些字段?那怎么样sockaddr_in?
可我只是投sockaddr_in来sockaddr,并把它比真实的sockaddr?
正如大多数C程序员所知,你无法直接比较两种结构.
考虑:
void isequal(MY_STRUCT a, MY_STRUCT b)
{
if (a == b)
{
puts("equal");
}
else
{
puts("not equal");
}
}
Run Code Online (Sandbox Code Playgroud)
该a==b比较将AFAIK扔在任何合理的C语言编译器编译错误,因为C标准不允许内置结构比较.使用memcmp的变通方法当然是一个坏主意,因为对齐,打包,位域等,所以我们最终逐个元素比较函数.
另一方面,它允许结构分配,例如a = b完全合法.很明显,编译器可以相当简单地处理这个问题,为什么不进行比较呢?
我唯一的想法是结构分配可能与memcpy()非常接近,因为对齐等因素无关紧要.另一方面,比较可能更复杂.或者这是我缺少的东西?
显然,我知道通过元素比较做一个简单的元素不一定足够,例如,如果结构包含指向字符串的指针,但在某些情况下它会有用.
假设我有以下结构:
typedef struct
{
unsigned field1 :1;
unsigned field2 :1;
unsigned field3 :1;
} mytype;
Run Code Online (Sandbox Code Playgroud)
前3位将可用,但sizeof(mytype)将返回4,这意味着29位填充.我的问题是,标准保证的这些填充位是否由语句初始化为零:
mytype testfields = {0};
Run Code Online (Sandbox Code Playgroud)
要么:
mytype myfields = {1, 1, 1};
Run Code Online (Sandbox Code Playgroud)
这样,memcmp()假设位4..29为零,执行以下操作是安全的,因此不会影响比较:
if ( memcmp(&myfields, &testfields, sizeof(myfields)) == 0 )
printf("Fields have no bits set\n");
else
printf("Fields have bits set\n");
Run Code Online (Sandbox Code Playgroud) 假设我有一个如下所示的结构:
struct Struct {
char Char;
int Int;
};
Run Code Online (Sandbox Code Playgroud)
并且sizeof( int )大于1并且编译器为Char成员变量添加填充- 编译器生成的代码是否允许更改填充字节的值?
我的意思是,如果我使用指针算法并将一些数据写入Char成员变量周围的填充字节,稍后进行variable.Char =分配是否有可能编译器生成的代码也会覆盖一些填充字节?
作为比较操作数的结构不可用是C中更明显的事情之一(对我而言)没有多大意义.结构可以通过值传递并通过赋值复制,但==不是为它们指定的.
下面是C11标准(草案)的相关部分,它们定义了相等运算符(==和!=)和简单赋值运算符(=)的约束.注意在等式运算符的约束中缺少结构和联合.(除了_Atomic在C99中没有处理措辞是相同的).
6.5.9平等运营商
约束
以下其中一项应持有:
- 两个操作数都有算术类型;
- 两个操作数都是指向兼容类型的限定或非限定版本的指针;
- 一个操作数是指向对象类型的指针,另一个是指向合格或非限定版本的void的指针; 要么
- 一个操作数是一个指针,另一个是空指针常量.
6.5.16.1简单分配
约束
以下其中一项应持有:
- 左操作数具有原子,限定或非限定算术类型,右边有算术类型;
- 左操作数具有与右侧类型兼容的结构或联合类型的原子,限定或非限定版本;
- 左操作数具有原子,限定或非限定指针类型,并且(考虑左值操作数在左值转换后将具有的类型)两个操作数都是指向兼容类型的限定或非限定版本的指针,左侧指向的类型具有全部右边指出的那种限定词;
- 左操作数具有原子,限定或非限定指针类型,并且(考虑左值操作数在左值转换后将具有的类型)一个操作数是指向对象类型的指针,另一个是指向合格或非限定版本的指针void,左边指向的类型具有右边指向的所有类型的限定符;
- 左操作数是一个原子,限定或非限定指针,右边是一个空指针常量; 要么
- 左操作数的类型为atomic,qualified或nonqualified _Bool,右边是指针.
任何人都可以解释为什么存在这种差异(没有推测)?
代码1:
struct demo
{
int a;
}d[2];
int main()
{
d[0].a=5;
d[1]=d[0];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这段代码工作正常
代码2:
struct demo
{
int a;
}d[2];
int main()
{
d[0].a=5;
d[1]=d[0];
if(d[0]==d[1])
{
printf("hello");
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
此代码给出错误
error: invalid operands to binary == (have 'struct demo' and 'struct demo')
Run Code Online (Sandbox Code Playgroud)
为什么在Code 2中出现此错误?