Tag: 指针

“解除引用”这个词来自哪里?

这个问题将从N1570草案中提取信息 ,所以基本上是C11。 通俗地说,取消引用指针意味着将一元*运算符应用于指针。 草案文件中只有一个“解除引用”一词的地方(没有“解除引用”的例子),它在脚注中: 102)[…] 用于通过一元*运算符解除引用指针的无效值包括空指针,为指向的对象类型不恰当地对齐的地址,以及对象在其生命周期结束后的地址 据我所知,一元*运算符实际上被称为“间接运算符”,如§6.5.3.2所示: 6.5.3.2地址和间接运营商 4一元*运算符表示间接。 […] 同时,它在附件§J.2中被明确地称为间接运算符: – 对象的值由array-subscript [] ,member-access访问. 或−> ,地址&或间接*运算符或在创建地址常量(6.6)时强制转换的指针。 那么在C中谈论“解除引用指针”是否正确或者这是否过于迂腐? 术语来自哪里? (由于§6.5.2.1,我可以给[]传递称为“引用”

联盟规模大于预期。 如何在这里进行类型对齐?

#include union u1 { struct { int *i; } s1; struct { int i, j; } s2; }; union u2 { struct { int *i, j; } s1; struct { int i, j; } s2; }; int main(void) { printf(” size of int: %zu\n”, sizeof(int)); printf(“size of int pointer: %zu\n”, sizeof(int *)); printf(” size of […]

指针转换为与qsort一起使用

从我正在阅读的书中复制的代码片段手: /* scmp: string compare of *p1 and *p2 */ int scmp(const void *p1, const void *p2) { char *v1, *v2; v1 = *(char **) p1; v2 = *(char **) p2; return strcmp(v1, v2); } 此函数与qsort一起用于对字符串数组进行排序。 我不明白的一点是,为什么v1 = *(char **) p1; 而不仅仅是v1 = (char *) p1; 或者甚至不会这样做; v1 = p1; ? 我想编译器应该自动对该分配进行类型转换。 或者甚至,考虑一下: /* scmp: […]

Swift转换C的uint64_t与使用自己的UInt64类型不同

我正在将应用程序从(Objective-)C移植到Swift,但必须使用用C编写的第三方框架。有一些不兼容的东西,比如typedef,它们被解释为Int,但必须传递给框架的function如UInts等。 因此,为了避免整个Swift应用程序中的常量转换操作,我决定将C头文件传输到Swift,所有类型的II都需要它们在一个地方。 我能够转移几乎所有的东西,并克服了很多障碍,但这一个: C头定义了一个包含uint64_t变量的结构。 此结构用于将数据作为指针传输到回调函数。 回调函数将void指针作为参数,我必须使用UnsafeMutablePointer操作将其转换为结构的类型(或者如果合适的话,还是标题的另一个结构)。 只要我使用导入时由Swift自动转换的C头中的原始结构,所有的转换和内存访问都可以正常工作。 但是,在Swift中手动复制结构并不是“字节匹配”。 让我向您展示一个这种情况的简化示例: 在CApiHeader.h文件中有类似的东西 typedef struct{ uint32_t var01; uint64_t var02; uint8_t arr[2]; }MyStruct, *MyStructPtr; 根据我的理解,这里应该是Swift的等价物 struct MyStruct{ var01: UInt32 var02: UInt64 arr: (UInt8, UInt8) } 或者也应该有效的是这种元组符号 typealias MyStruct = ( var01: UInt32, var02: UInt64, arr: (UInt8, UInt8) ) 这可以正常工作,但不是只有UInt64类型。 好的,那会发生什么? 将指针转换为我自己的Swift MyStruct实现之一,从UInt64字段开始,将孔数据移位2个字节。 因此,在此示例中,两个arr字段都不在正确的位置,但在UInt64位内,其数量应为64。 所以它的接缝是UInt64字段只有48位。 这符合我的观察,如果我用这个替代品替换UIn64变量 struct MyStruct{ var01: UInt32 […]

在某些情况下,您可以使用限制指针来访问同一个对象吗?

大多数限制的定义都说它是程序员对编译器的承诺,在指针的生命周期中,指针是访问对象的唯一方式。 这允许编译器优化输出,因为它知道它只能由一个指针访问,因此只能由它来改变。 如果我理解正确通常意味着程序不必重新加载指针指向的值。 如果这是正确的,那么当restrict关键字应该可用时应该有一些例外,即使它违背了应该如何使用它的意图。 我想到的一件事是指针指向的数据在指针的生命周期内从未实际发生过变化。 在这种情况下,即使指针指向同一位置,也不需要重新加载数据,因为它们在指针的生命周期中不会改变。 例如: int max(int *restrict a, int *restrict b) { return((*a > *b) ? *a : *b); } int main(void) { int num = 3; int max = max(&num, &num); } 这是对限制的有效使用,即使它与它应该如何使用相反吗? 使用像这样的restrict关键字会导致未定义的行为吗?

将指针强制转换为char指针会导致C中的数据丢失?

我有以下代码: #include #include int main(int argc, char *argv[]) { int n = 260; int *p = &n; char *pp = (char*)p; *pp = 0; printf(“n = %d\n”, n); system(“PAUSE”); return 0; } 程序的输出放置为n = 256 。 我可能理解为什么,但我不确定。 请问有人给我一个明确的解释吗? 非常感谢。

从堆栈地址形成指针范围是不确定的行为?

一些C或C ++程序员惊讶地发现即使存储无效指针也是未定义的行为 。 但是,对于堆或堆栈数组,可以存储一个超过数组末尾的地址,这允许您存储“结束”位置以便在循环中使用。 但是从单个堆栈变量形成指针范围是未定义的行为,如: char c = ‘X’; char* begin = &c; char* end = begin + 1; for (; begin != end; ++begin) { /* do something */ } 虽然上面的例子很没用,但是如果某个函数需要一个指针范围,并且你只有一个值来传递它,那么这可能很有用。 这是未定义的行为吗?

为什么在释放指向它的指针后仍然可以访问结构的成员?

如果我定义一个结构…… struct LinkNode { int node_val; struct LinkNode *next_node; }; 然后创建一个指向它的指针…… struct LinkNode *mynode = malloc(sizeof(struct LinkNode)); …然后终于免费()它…… free(mynode); …我仍然可以访问结构的’next_node’成员。 mynode->next_node 我的问题是: 底层机制的哪一部分跟踪这个内存块应该代表一个结构LinkNode的事实? 我是C的新手,我期望在我使用指向我的LinkNode的指针上的free()后,我将无法再访问该结构的成员。 我期待某种“不再可用”的警告。 我想更多地了解基础流程的工作原理。

C宏 – 检查变量是否为指针

刚开始考虑这一点,并想知道是否有一些“好”的方法来检查传递给c中的宏的变量是否是一个指针? 即: #define IS_PTR(x) something int a; #if IS_PTR(a) printf(“a pointer we have\n”); #else printf(“not a pointer we have\n”); #endif 这个想法并不是说这是在运行时完成而是编译时间,如下所示:我们根据变量是否为指针得到不同的代码。 所以我希望IS_PTR()以某种方式评估某种常量表达式。 我是怎么回事这个想法的? 这一切都有可能吗?在这种情况下会怎样做? 提前致谢!

为什么这个函数返回垃圾值

我正在编写一个程序并面临这个问题,以下函数用于返回垃圾值: int* foo(int temp){ int x = temp; return &x; } 当我修改它时,它工作正常: int* foo(int *temp){ int *x = temp; return x } 第一个版本出了什么问题?