- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
struct message {
uint8_t start;
uint16_t length;
uint8_t data[10];
uint8_t checkSum;
} __attribute__((packed));
struct message devices[10];
void request(struct message *msg) {
struct request *req = (struct request *)&msg->data;
req->operation = 1;
req->requesterAddress = MASTER_ADDRESS;
}
request(&devices[0]);
我的问题是,为什么“&msg->data”处有“&”符号?
我的理解是函数“request”接收一个指向结构的指针“msg”。 msg->data 从“msg”指向的结构中检索指针“data”(“data”是一个数组),然后将其转换为另一个指针类型(struct request *)。
所以该部分应该是 (struct request *)msg->data;那么为什么要使用&符号呢?
最佳答案
嗯,这段代码不是 C 语言,因为 __attribute__((packed))
仅在 gcc 和其他一些特定实现中有效,但在标准 C 中绝对不存在。
但提供sizeof(struct message) <= 10
,其余代码是根据 4. Conformance
的正确代码但包含未指定的行为,并且可能包含未定义的行为,具体取决于实现
request(&devices[0]);
和void request(struct message *msg) {...}
:好的:request
预计 struct message *
并接收 struct message
数组的第一个元素的地址- 这里一切都很好struct request *req = (struct request *)&msg->data;
: 这是最有趣的部分。
msg->data
是一个char数组,即一个聚合。聚合的地址是其第一个字节的地址。不同的说法(char *) &msg-> data
(聚合的第一个字节的地址)与 msg->data
相同(数组衰减为指向其第一个元素的指针)(struct request *)&msg->data;
指向 char 的指针被转换为指向 struct request
的指针。根据实现的不同,没有任何东西可以保证指针正确对齐。如果不是,则根据 6.3.2.3 指针第 7 节,这是未定义的行为。如果是,根据 6.5 表达式第 6-7 节,我们仍然具有未指定的行为,因为新指针将用于存储尚未定义的元素。 char[10]
的声明类型。但这将被所有已知的实现所接受,因为它们在内部处理相同的 char 数组(显式类型)和分配的内存(没有声明的类型) - 仅仅因为它们需要实现 malloc
(参见Is it possible to write a conformant implementation of malloc in C?)其余代码没有其他问题。但需要注意的是,如果__attribute__(packed)
荣幸地实现,现场data
将是结构体的第三个字节,这给出了奇怪的对齐方式。这可能会导致需要对某些类型进行严格对齐的实现崩溃。
来自 C99 n1256 草案的引用
- Conformance
...
2 If a ‘‘shall’’ or ‘‘shall not’’ requirement that appears outside of a constraint is violated, the behavior is undefined...
3 A program that is correct in all other aspects, operating on correct data, containing unspecified behavior shall be a correct program...
6.3.2.3 Pointers
...
7 A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined. Otherwise, when converted back again, the result shall compare equal to the original pointer. When a pointer to an object is converted to a pointer to a character type, the result points to the lowest addressed byte of the object.
6.5 Expressions
...
6 The effective type of an object for an access to its stored value is the declared type of the object, if any. If a value is stored into an object having no declared type through an lvalue having a type that is not a character type, then the type of the lvalue becomes the effective type of the object for that access and for subsequent accesses that do not modify the stored value. If a value is copied into an object having no declared type using memcpy or memmove, or is copied as an array of character type, then the effective type of the modified object for that access and for subsequent accesses that do not modify the value is the effective type of the object from which the value is copied, if it has one. For all other accesses to an object having no declared type, the effective type of the object is simply the type of the lvalue used for the access.
7 An object shall have its stored value accessed only by an lvalue expression that has one of the following types:
- atype compatible with the effective type of the object,
- aqualified version of a type compatible with the effective type of the object,
- a type that is the signed or unsigned type corresponding to the effective type of the object,
- a type that is the signed or unsigned type corresponding to a qualified version of the effective type of the object,
- an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union), or
- a character type.
关于c - 从结构体访问数组并将其转换为指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43332618/
我刚接触 C 语言几周,所以对它还很陌生。 我见过这样的事情 * (variable-name) = -* (variable-name) 在讲义中,但它到底会做什么?它会否定所指向的值吗? 最佳答案
我有一个指向内存地址的void 指针。然后,我做 int 指针 = void 指针 float 指针 = void 指针 然后,取消引用它们以获取值。 { int x = 25; vo
我正在与计算机控制的泵进行一些串行端口通信,我用来通信的 createfile 函数需要将 com 端口名称解析为 wchar_t 指针。 我也在使用 QT 创建一个表单并获取 com 端口名称作为
#include "stdio.h" #include "malloc.h" int main() { char*x=(char*)malloc(1024); *(x+2)=3; --
#include #include main() { int an_int; void *void_pointer = &an_int; double *double_ptr = void
对于每个时间步长,我都有一个二维矩阵 a[ix][iz],ix 从 0 到 nx-1 和 iz 从 0 到 nz-1。 为了组装所有时间步长的矩阵,我定义了一个长度为 nx*nz*nt 的 3D 指针
我有一个函数,它接受一个指向 char ** 的指针并用字符串填充它(我猜是一个字符串数组)。 *list_of_strings* 在函数内部分配内存。 char * *list_of_strings
我试图了解当涉及到字符和字符串时,内存分配是如何工作的。 我知道声明的数组的名称就像指向数组第一个元素的指针,但该数组将驻留在内存的堆栈中。 另一方面,当我们想要使用内存堆时,我们使用 malloc,
我有一个 C 语言的 .DLL 文件。该 DLL 中所有函数所需的主要结构具有以下形式。 typedef struct { char *snsAccessID; char *
我得到了以下数组: let arr = [ { children: [ { children: [], current: tru
#include int main(void) { int i; int *ptr = (int *) malloc(5 * sizeof(int)); for (i=0;
我正在编写一个程序,它接受一个三位数整数并将其分成两个整数。 224 将变为 220 和 4。 114 将变为 110 和 4。 基本上,您可以使用模数来完成。我写了我认为应该工作的东西,编译器一直说
好吧,我对 C++ 很陌生,我确定这个问题已经在某个地方得到了回答,而且也很简单,但我似乎找不到答案.... 我有一个自定义数组类,我将其用作练习来尝试了解其工作原理,其定义如下: 标题: class
1) this 指针与其他指针有何不同?据我了解,指针指向堆中的内存。如果有指向它们的指针,这是否意味着对象总是在堆中构造? 2)我们可以在 move 构造函数或 move 赋值中窃取this指针吗?
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: C : pointer to struct in the struct definition 在我的初学者类
我有两个指向指针的结构指针 typedef struct Square { ... ... }Square; Square **s1; //Representing 2D array of say,
变量在内存中是如何定位的?我有这个代码 int w=1; int x=1; int y=1; int z=1; int main(int argc, char** argv) { printf
#include #include main() { char *q[]={"black","white","red"}; printf("%s",*q+3); getch()
我在“C”类中有以下函数 class C { template void Func1(int x); template void Func2(int x); }; template void
我在64位linux下使用c++,编译器(g++)也是64位的。当我打印某个变量的地址时,例如一个整数,它应该打印一个 64 位整数,但实际上它打印了一个 48 位整数。 int i; cout <<
我是一名优秀的程序员,十分优秀!