如何理解函数函数参数中的星号(*)?

时间:2016-02-21 03:58:37

标签: c++ c

这是我困惑的事情:

extern int sigsegv_leave_handler (
    void (*continuation) (void*, void*, void*), 
    void* cont_arg1, void* cont_arg2, void* cont_arg3);

我不明白*continuation **continuation的用途是什么

更新

完整代码位于linux的“/usr/include/sigsegv.h”中

更新

我使用sigsegv_leave_handler如下:

void cont(void *fault_addr, void *arg1, void *arg2) {
//    rb_raise(rb_eTypeError, "type err");
    rraise(SEGV, NULL);
}

int handle_segv(void *fault_addr, int serious) {
    sigsegv_leave_handler(cont, fault_addr, NULL, NULL);
}

2 个答案:

答案 0 :(得分:3)

void (*continuation) (void*, void*, void*)

只是一个声明,其中continuation是一个指向函数的指针,它指向3个void *指针但没有返回任何内容( void返回类型)。< / p>

这是你向函数声明指针的方法,

RETURN_TYPE (*IDENTIFIER)(... PARAMETERS WITH THEIR TYPES AS USUAL ...);

答案 1 :(得分:1)

使用的有用工具是C gibberish ↔ English

# Load Packages
library(MonetDB.R)
library(MonetDBLite)
library(DBI)   # suggested in comments and needed on OSX
library(survey)

# Load Data
data(api)

# Multiplicate data observations by 10000 
apiclus1 <- apiclus1[rep(seq_len(nrow(apiclus1)), 10000), ]

# create a count variable
apiclus1$vcount <- 1

# create survey design
dclus1 <- svydesign(id=~dnum, weights=~pw, data=apiclus1, fpc=~fpc)


dbfolder <- tempdir()

db <- dbConnect( MonetDBLite() , dbfolder )
dbWriteTable( db , 'apiclus1' , apiclus1 )


db_dclus1 <-
    svydesign(
        weight = ~pw ,
        id = ~dnum ,
        data = "apiclus1" , 
        dbtype = "MonetDBLite" ,
        dbname = dbfolder ,
        fpc = ~fpc
    )

# you provided a design without strata,
# so type="JK1" matches that most closely.
# but see survey:::as.svrepdesign for other linearization-to-replication options
jk1w <- jk1weights( psu = apiclus1$dnum , fpc = apiclus1$fpc )

# after the replicate-weights have been constructed,
# here's the `svrepdesign` call..
jk1w_dclus1 <-
    svrepdesign(
        weight = ~pw ,
        type = "JK1" ,
        repweights = jk1w$repweights ,
        combined.weights = FALSE ,
        scale = jk1w$scale ,
        rscales = jk1w$rscales ,
        data = 'apiclus1' ,
        dbtype = "MonetDBLite" ,
        dbname = dbfolder
    )

# slow
system.time(res1 <- svyby(~vcount,~stype+dnum+cname,design = dclus1,svytotal))
# > system.time(res1 <- svyby(~vcount,~stype+dnum+cname,design = dclus1,svytotal))
   # user  system elapsed 
  # 17.40    2.86   20.27 


# faster
system.time(res2 <- svyby(~vcount,~stype+dnum+cname,design = db_dclus1,svytotal))
# > system.time(res2 <- svyby(~vcount,~stype+dnum+cname,design = db_dclus1,svytotal))
   # user  system elapsed 
  # 13.00    1.20   14.18 


# fastest
system.time(res3 <- svyby(~vcount,~stype+dnum+cname,design = jk1w_dclus1,svytotal))
# > system.time(res3 <- svyby(~vcount,~stype+dnum+cname,design = jk1w_dclus1,svytotal))
   # user  system elapsed 
  # 10.75    1.19   11.96 

# same standard errors across the board
all.equal( SE( res1 ) , SE( res2 ) )
all.equal( SE( res2 ) , SE( res3 ) )
# NOTE: the replicate-weighted design will be slightly different
# for certain designs.  however this technique is defensible
# and gets used in 
# https://github.com/ajdamico/asdfree/tree/master/Censo%20Demografico


# at the point you do not care about standard errors,
# learn some sql:
system.time( res4 <- dbGetQuery( db , "SELECT stype , dnum , cname , SUM( pw ) FROM apiclus1 GROUP BY stype , dnum , cname" ) )
# because this is near-instantaneous, no matter how much data you have.

# same numbers as res1:
all.equal( as.numeric( sort( coef( res1 ) ) ) , sort( res4$L1 ) )
# > system.time( res4 <- dbGetQuery( db , "SELECT stype , dnum , cname , SUM( pw ) FROM apiclus1 GROUP BY stype , dnum , cname" ) )
   # user  system elapsed 
   # 0.15    0.20    0.23 
  

将sigsegv_leave_handler声明为extern函数(指向函数的指针(指向void的指针,指向void的指针,指向void的指针)返回void,指向void的指针,指向void的指针,指向void的指针)返回int

或者换句话说,extern int sigsegv_leave_handler (void (*) (void*, void*, void*), void* , void* , void* ); 接受4个参数并返回sigsegv_leave_handler()

int
  

* in * continuation有什么用?

显示参数是指向函数的指针。

1) pointer to a function which takes 3 void * pointers and returns void
void (*f) (void*, void*, void*) 

2) pointer to void
void *

3) pointer to void
void *

4) pointer to void
void *