我写这篇文章主要是为了澄清我在 Stackoverflow 上偶然发现的一些关于函数指针的令人困惑/误导的信息。
让我们从一个例子开始:
#include <iostream>
void func ()
{
std::cout<<"func here"<<'\n';
}
int main()
{
void (*fp)()=func;
void (&fref)()=func;
func();//call through function
(&func)();//call through function pointer
(*fp)();//call through function
fp();//call through function pointer
fref();//call through function
(&fref)();//call through function pointer
}
Run Code Online (Sandbox Code Playgroud)
这打印:
func here
func here
func here
func here
func here
func here
Run Code Online (Sandbox Code Playgroud)
可以看出,由于函数到函数指针的衰减cppreference,大多数时候可以使用函数来代替函数指针。
函数类型 T 的左值可以隐式转换为指向该函数的纯右值指针。这不适用于非静态成员函数,因为不存在引用非静态成员函数的左值。
但除此之外,函数指针看起来也可以用来代替函数,因为我可以使用它来调用函数而无需显式取消引用。
另请注意,您不需要使用一元 * 来通过函数指针进行调用;两者 (*p1_foo)(); 和 (p1_foo)(); 由于函数到函数指针的转换,具有相同的结果。
还有一个双重的便利:调用位置的函数指针会自动转换为函数值,因此您不必编写 * 来通过函数指针进行调用。
让它看起来好像存在一个隐式函数指针来进行函数转换。
以下代码使用 avolatile uint8_t而不是 avolatile sig_atomic_t作为 C 标准要求,因为在 avr 平台上该类型sig_atomic_t不可用。
这仍然是合法的代码吗?使用合法吗__SIG_ATOMIC_TYPE__?
是否需要包含cli()/sei()宏?
#include <stdint.h>
#include <signal.h>
#include <avr/interrupt.h>
volatile uint8_t flag;
//volatile sig_atomic_t flag; // not available in avr-gcc
//volatile __SIG_ATOMIC_TYPE__ flag; // ok?
void isr() __asm__("__vector_5") __attribute__ ((__signal__, __used__, __externally_visible__));
void isr() {
flag = 1;
}
void func(void) {
for (uint8_t i=0; i<20; i++) {
flag = !flag;
}
}
Run Code Online (Sandbox Code Playgroud) 看代码:
#include <stdio.h>
#include <stdint.h>
int main() {
char foo[512]={};
printf("%d", *((uint32_t*)foo));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我很难理解它的*((uint32_t*)foo))作用,在数组中使用不同的值我得到各种返回值。它到底指向什么,那么返回值是什么呢?
我有一个对象S,其中包含调用的方法getstaus().现在来自后端的状态值也可以null,所以我通过以下方式检查:
if (S.getStatus().equals(null))
{}
Run Code Online (Sandbox Code Playgroud)
请让我知道这是正确的方法,还是没有比这更好的方法.
文件ac:
#include<stdio.h>
int main(int argc, const char *argv[])
{
double r = 0;
r = call(10.0,2.0);
printf("r:%lf\n",r);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
函数call()在一个静态库中,如:
文件call.c
#include<stdio.h>
double call(double a,double b){
double c;
c = a + b;
printf("c :%lf\n",c);
return c;
}
Run Code Online (Sandbox Code Playgroud)
我使用的命令是
gcc -c call.c -o call.o
ar rcs libcall.a call.o
gcc -o a a.c -lcall -L.
Run Code Online (Sandbox Code Playgroud)
那么为什么结果不是12?如果我将double类型更改为int类型,则结果为12.
ISO 9899:2018已经有一段时间可以从ISO获得.变更清单:
非正式地,这个版本的标准已被称为C17一段时间,但ISO文件将是9899:2018.所以我想知道我们应该把它叫做C17还是C18.
为了不引起基于意见的答案,我的问题是:有哪些规范来源将此标准标记为"C17"或"C18"?
最规范的来源当然是ISO标准本身.鉴于此,为了保持一致性,标准应称为C18:
它发布于2018年,而不是2017年.所以我认为我们应该称它为C18?
虽然作为另一个例子,我知道的gcc创造了一个编译器开关-std=c17,根据此.gcc手册有点规范.他们打算保留这个名字吗?那些像clang和icc这样的人呢?
有一些共识吗?委员会的意见?
我在一次采访中被要求序列化数据(因此它可以存储在缓冲区中并通过某个网络发送)。这就是我想出的-
struct AMG_ANGLES {
float yaw;
float pitch;
float roll;
};
char b[sizeof(struct AMG_ANGLES)];
char* encode(struct AMG_ANGLES *a)
{
std::memcpy(b, &a, sizeof(struct AMG_ANGLES));
return b;
}
void decode(char* data)
{
// check endianess
AMG_ANGLES *tmp; //Re-make the struct
std::memcpy(&tmp, data, sizeof(tmp));
}
Run Code Online (Sandbox Code Playgroud)
这样对吗?任何人都可以提供替代设计吗?我没有收到回电,所以我只是想了解我可以改进的地方。
答案是90.但这是什么逻辑?如果我写这个j =(4,5); 然后回答是5.
#include<stdio.h>
void main()
{
int j;
j=(4,5,90);
printf("%d\n",j);
}
Run Code Online (Sandbox Code Playgroud) 我需要处理2D矩阵,但经过一些分配后,一切都会出错.这基本上是指令.
这是代码:
int matA[1][1], matB[1][7], matRes[1][7];
memset (matA, 0, sizeof (matA));
memset (matB, 0, sizeof (matB));
memset (matRes, 0, sizeof (matRes));
printf("test0 :%d \n",matB[1][0]);
//matrice de fonction
matB[1][0]= 0;
printf("test1 :%d \n",matB[1][0]);
matB[1][1]= matB[0][2]= matB[0][3]= 0;
printf("test2 :%d \n",matB[1][0]);
matB[0][0]= matB[0][4]= matB[0][6]= matB[1][2]= matB[1][4]= matB[1][5]= 1;
printf("test3 :%d \n",matB[1][0]);
matB[0][1]= matB[0][5]= matB[0][7]= matB[1][3]= matB[1][6]= matB[1][7]= -1;
printf("test4 :%d \n",matB[1][0]);
//matrice d'entrée
matA[0][1]= matA[1][0] = 0;
printf("test5 :%d \n",matB[1][0]);
matA[0][0]= X;
printf("test6 :%d \n",matB[1][0]);
matA[1][1]= Y;
printf("test7 :%d \n",matB[1][0]);
Run Code Online (Sandbox Code Playgroud)
并输出:
test0 …Run Code Online (Sandbox Code Playgroud)