考虑以下C代码: typedef char * MYCHAR; MYCHAR x; 我的理解是结果是x是“char”类型的指针。 但是,如果x的声明远离typedef命令,则代码的人类读者不会立即知道x是指针。 或者,可以使用 typedef char MYCHAR; MYCHAR *x; 哪个被认为是更好的forms? 这不仅仅是风格问题吗?
如果有人回答我的问题,请不要告诉我使用C ++ 。 所以,我在C中创建了一个使用面向对象方法的小型库。 我选择在C中使用两种主要的inheritance方法中较不常见的方法:将基类型的成员复制到派生类型的开头。 像这样的东西: struct base { int a; int b; char c; }; struct derived { int a; int b; char c; unsigned int d; void (*virtual_method)(int, char); }; 这种方法不如另一种方法(基类型的实例作为派生类型的第一个成员)受欢迎,因为 从技术上讲,没有标准保证基础和派生结构的第一个共同成员将具有相同的抵消。 但是,除了其中一个结构被打包而另一个结构没有被打包的情况之外,它们将在大多数(如果不是全部)已知编译器上具有相同的偏移量。 这种方法最严重的缺陷:它违反了严格的别名 。 将指向派生结构的指针转换为其基类型然后解除引用指针在技术上是未定义的行为。 但是,与其他方法相比,它也有其优点: 更少详细:访问已inheritance的派生结构的成员与访问尚未inheritance的结构相同,而不是转换为基类型, 然后访问所需的成员; 这实际上是真正的inheritance而不是构成 ; 虽然可能需要一些预处理器滥用,但它与其他方法一样容易实现; 我们可以得到一个实际多重inheritance的半生不熟的forms,我们可以从几个基类型inheritance,但只能转换为其中一个。 我一直在寻找使我的库编译和使用强制执行严格别名(如gcc )的编译器正确工作的可能性,而无需用户手动关闭它。 以下是我研究过的可能性: 工会。 遗憾的是,由于以下几个原因,这些是禁忌: 详细程度回归! 要遵循通过联合访问2个结构的第一个共同成员的标准规则,必须(从C99开始)明确使用联合来访问第一个共同成员。 我们需要特殊的语法来访问联合中每种类型的成员! 空间。 考虑一个inheritance层次结构。 […]
我在尝试编译代码时遇到错误。 错误如下: warning: incompatible pointer types passing ‘void *(threadData *)’ to parameter of type ‘void * (*)(void *)’ [-Wincompatible-pointer-types] pthread_create(&threads[id], NULL, start,&data[id]); 我正在尝试将一个结构传递给函数, void * start(threadData* data) ,这一直让我失望。 有任何想法吗?
为什么这个char变量的大小等于1? int main(){ char s1[] = “hello”; fprintf(stderr, “(*s1) : %i\n”, sizeof(*s1) ) // prints out 1 }
当两个指针指向同一个地址时会发生什么? 这会导致安全问题吗?
想看看是否有人知道它是否可以交换C函数……? void swap2(int(*a)(int), int(*b)(int)) { int(*temp)(int) = a; *a = *b; *b = temp; // Gives ‘Non-object type ‘int (int)’ is not assignable } swap2(&funcA, &funcB); 编辑 关于意图的更多数据 – 下面提供了一些答案,它们可以使用typedef创建函数ptr,将它们指向函数并切换它们,从而可以成功调用新交换的ptrs。 但是在交换后以原始名称调用函数显示没有变化。 基本上我正在寻找相当于objc“swizzle”的交流。 我开始认为这是不可能的,因为c完全没有reflection,并且需要实际修改二进制本身(显然不可行)。 d: 欢迎评论。
以下代码是100%可移植的吗? int a=10; size_t size_of_int = (char *)(&a+1)-(char*)(&a); // No problem here? std::cout<<size_of_int;// or printf("%zu",size_of_int); PS :问题仅限于学习目的。 所以请不要给出像Use sizeof()等的答案
为指针使用索引括号是否也取消引用它? 为什么打印这个指针的第0个索引两次最终打印两个不同的东西? #include #include #include using namespace std; int *p; void fn() { int num[1]; num[0]=99; p = num; } int main() { fn(); cout << p[0] << " " << p[0]; }
有两个相关的C标准规则: C99标准, 6.3.2.3 : 指向void的指针可以转换为指向任何不完整或对象类型的指针。 指向任何不完整或对象类型的指针可能会转换为指向void的指针并再次返回; 结果应该等于原始指针。 并且7.20.1.4 : 下面的类型指定一个无符号整数类型,其属性是任何有效的void指针都可以转换为此类型,然后转换回指向void的指针,结果将与原始指针进行比较: uintptr_t 这意味着,以下代码符合: int *p = NULL; void *q = (void*)p; uintptr_t s = (uintptr_t)q; 但它真的需要两步演员吗? 如果执行以下操作,编译器是否会执行隐式中间转换: int *p = NULL; uintptr_t s = (uintptr_t)p; (好吧,它可能会出现在大多数编译器上,但我的问题是标准符合性)
这两行代码有什么区别? int *ptr = &x; 和 void* q = &x; int* p = q; 我对C和指针的概念很新 – 主要是用Java教过 – 所以有点困惑。 提前致谢。