小编Lun*_*din的帖子

是否存在从函数指针到函数的隐式转换?

我写这篇文章主要是为了澄清我在 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 的左值可以隐式转换为指向该函数的纯右值指针。这不适用于非静态成员函数,因为不存在引用非静态成员函数的左值。

但除此之外,函数指针看起来也可以用来代替函数,因为我可以使用它来调用函数而无需显式取消引用。

此外,这个 Stackoverflow 答案

另请注意,您不需要使用一元 * 来通过函数指针进行调用;两者 (*p1_foo)(); 和 (p1_foo)(); 由于函数到函数指针的转换,具有相同的结果。

以及这个 Stackoverflow 的答案

还有一个双重的便利:调用位置的函数指针会自动转换为函数值,因此您不必编写 * 来通过函数指针进行调用。

让它看起来好像存在一个隐式函数指针来进行函数转换。

c++ pointers function language-lawyer

0
推荐指数
1
解决办法
324
查看次数

使用“易失性 uint8_t”代替“易失性 sig_atomic_t”是否合法?

以下代码使用 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)

c embedded avr interrupt-handling language-lawyer

0
推荐指数
1
解决办法
304
查看次数

*((uint32_t)foo) 返回什么

看代码:

#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))作用,在数组中使用不同的值我得到各种返回值。它到底指向什么,那么返回值是什么呢?

c pointers stdint

0
推荐指数
1
解决办法
125
查看次数

检查对象是否为null值

我有一个对象S,其中包含调用的方法getstaus().现在来自后端的状态值也可以null,所以我通过以下方式检查:

if (S.getStatus().equals(null)) 
{}
Run Code Online (Sandbox Code Playgroud)

请让我知道这是正确的方法,还是没有比这更好的方法.

java

-1
推荐指数
1
解决办法
114
查看次数

为什么静态库函数的值错误?

文件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.

c linux static-libraries

-1
推荐指数
1
解决办法
140
查看次数

静态内联函数比宏更受欢迎.这是什么意思?

静态内联函数比宏更受欢迎.它们提供类型安全.

这是什么意思?任何人都可以解释,如果可能的话,举个例子吗?

c

-1
推荐指数
1
解决办法
142
查看次数

我们应该称它为C17还是C18?

ISO 9899:2018已经有一段时间可以从ISO获得.变更清单:

什么是C17以及该语言有哪些变化?

非正式地,这个版本的标准已被称为C17一段时间,但ISO文件将是9899:2018.所以我想知道我们应该把它叫做C17还是C18.

为了不引起基于意见的答案,我的问题是:有哪些规范来源将此标准标记为"C17"或"C18"?

最规范的来源当然是ISO标准本身.鉴于此,为了保持一致性,标准应称为C18:

  • C90 = 9899:1990
  • C99 = 9899:1999
  • C11 = 9899:2011
  • C1x = 9899:2018

它发布于2018年,而不是2017年.所以我认为我们应该称它为C18?

虽然作为另一个例子,我知道的gcc创造了一个编译器开关-std=c17,根据.gcc手册有点规范.他们打算保留这个名字吗?那些像clang和icc这样的人呢?

有一些共识吗?委员会的意见?

c c11 c17

-1
推荐指数
1
解决办法
1385
查看次数

如何在C++中序列化结构数据?

我在一次采访中被要求序列化数据(因此它可以存储在缓冲区中并通过某个网络发送)。这就是我想出的-

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)

这样对吗?任何人都可以提供替代设计吗?我没有收到回电,所以我只是想了解我可以改进的地方。

c++ serialization

-1
推荐指数
1
解决办法
382
查看次数

任何人都可以解释这段代码的输出吗?

答案是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)

c

-2
推荐指数
1
解决办法
98
查看次数

将值分配给2D矩阵

我需要处理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)

c

-2
推荐指数
1
解决办法
90
查看次数