T*******x 发帖数: 8565 | 1 读typedef的trick是这样的:
你先把typedef这个关键字去掉,这个语句就变成了一个变量声明,
再加回typedef,就定义了一个这个变量所属的类型。
比如你这个
typedef void(Receiver::* Action)();
去掉这个typedef,就是一个函数指针变量的声明,
这个指针指向一个函数,这个函数1.没有参数2.没有返回值3.有一定的scope --
必须指向一个成员函数。加回typedef后,就定义了一个相应的类型。
请注意这两个的不同:
void func();
void (*func)();
前者是一个函数的prototype,后者是一个函数指针变量的声明,
我们这里要得是后者(去掉typedef之后)。 |
|
f****4 发帖数: 1359 | 2 不知道你想说啥。。。
C++ static 成员函数指针和非成员函数指针2者类型是不同的
class Function_pointer
{
public:
static int current(int);
int next(int n);
};
//static成员函数指针的类型是和c相同的所以不用instance就能直接调用
typedef int (*sf)(int n);
sf stcFunc= &Function_pointer::current;
cout<
//非static成员函数指针的类型则要求用instance才能调用
typedef int (Function_pointer::*f)(int n);
f fp1=&Function_pointer::next;
Function_pointer myFunc;
(myFunc.*fp1)(10);
这和cast,和引用没有任何关系
case |
|
t******4 发帖数: 134 | 3 送进函数之前存一个?
函数多一个参数专门往下传root指针?
啥目的呢
:如果函数参数是二叉树的指针,有没有办法可以把根指针保存下来? |
|
b****g 发帖数: 192 | 4 函数一共三个参数
貌似是执行完就在地址0x12fec8那里存一个整数,值为val1。
又在地址为val1的地方连着整出来9个int那么,这9个地方存的都是整数val2.
但是我不懂为什么p1也是参数呢?
在函数内部,p1指向的是地址为val1的地方,这里存着第一个val2.
那函数执行完了,p1作为形参指向的地方就可能不是地址val1啦,
那位什么还要把p1作为函数参数呢?
函数里面p1从来就没出现在等号右边,
p1出现在等号左边就一次,也不带型号,所以也不能传值啊。
那这个p1就毫无用处,等于说函数执行完了,函数外的p1还无改变,*p1也无改变。
难道出现这个p1就是为了考考动不动指针? |
|
d****i 发帖数: 4809 | 5 你的函数指针的定义不对,应该对应函数的argument, 比如
void subf(int a, void *ptr) {}
void (*PtoF)(int, void*);
至于下面两个为什么一样,函数指针用函数名赋值和用函数的地址是等效的,可以想象
成函数名就是函数的入口地址。
PtoF = subf;
PtoF = &subf; |
|
d****i 发帖数: 4809 | 6 你的函数指针的定义不对,应该对应函数的argument, 比如
void subf(int a, void *ptr) {}
void (*PtoF)(int, void*);
至于下面两个为什么一样,函数指针用函数名赋值和用函数的地址是等效的,可以想象
成函数名就是函数的入口地址。
PtoF = subf;
PtoF = &subf; |
|
s******u 发帖数: 501 | 7 通常如果把函数指针func作为函数foo的一个参数的话,可以这么写
int foo( int(*func)() )
{
return func();
}
然后作为函数指针,加不加这个*是没有区别的,所以简化成
int foo(int(func)()) { ... }
再接下来,函数的参数可以只给类型不给命名,表示我在函数内部不会使用到这个参数
,继续简化成
int foo(int()()) { ... }
因为没有函数变量的名字,所以第二个括号是可有可无的
int foo(int()) { ... }
把第一个int换成你这里的A,把第二个int换成你这里的B于是就有了
A a(B());
当然就是一个函数声明了 |
|
P*****i 发帖数: 63 | 8 看到这一块时感觉好烦呀,困惑有如当年刚见识指针的指针一般。
好吧,我能理解,每个处理普通字符的宏函数都有一个对应处理特殊字符的宏函数,有如%UPCASE之于%QUPCASE。后者的作用就是能无视&和%这两个特殊解析宏的字符。
但当书上这个例子一抛出,楼主便陷入了懵逼中。
%let a=begin;
%let b=%nrstr(&a);
%put UPCASE produces: %upcase(&b);
%put QUPCASE produces: %qupcase(&b);
嵌套的宏解析...
一点点来捋吧。首先,带%的func一定是跟宏相关,要能解析带&后面的字符串参数,将宏替换为相应的值,再以对应的普通函数处理。所以,%UPCASE 就是专门处理宏为参数的UPCASE函数。
在这个例子里,宏a对应的值解析为begin, 宏b的赋值因为无视&的存在,所以解析为&a。
那么,%UPCASE(&b)上来先对&b做解析,得到&a, 然后
下一步呢?
是函数表达式变成了UPCASE(&a), 还是UPCASE(begin)?
但无论是哪个分支,都不大像能得出结果小写的begin啊。
后面Q... 阅读全帖 |
|
b***i 发帖数: 3043 | 9 我的理解
java是pass by value。所以,传入一个整数作为参数到函数里面是不能改变函数外面
那个 变量的值 的。
而那些复杂的类,传入的是类的地址的值。在这里,类的值就是变量地址的值。因为
java里面不讲地址,但本质上就是堆栈里面的地址。当你传入类变量的地址,当然可以
根据地址改变地址指向的那个数据,但是不能改变该变量本身的地址。这和C语言里面
传入一个指针,可以改变指针指向的数据,但是不能改变指针本身是一样的。 |
|
z****e 发帖数: 2024 | 10 非常赞红猪侠说的那个"&".我也受教了。
thrust以前也提醒过这个"&"。需要牢记啊!
我再狗尾续貂罗嗦几句,你可以这样理解:
成员函数指针的定义是:
返回值 (类名::*指针名)(参数表)=&类名:: 成员函数名;
成员函数名: foo
返回值: int
参数表: 空
类名:X
指针名: Y::p
由于 p 是static的,所以必须定义。而,
int (X::*Y::p)() = &X::foo;
就是p的定义。 |
|
w***g 发帖数: 5958 | 11 不知道你对C语言里面的函数指针有什么看法,符合你说的作为参数传递,作为返回值
,可以赋给变量三个条件。C++里面的lambda只是函数指针的语法糖而已。java,
python这些语言里的lambda也都更像函数指针的语法糖。这些都是伪functional
programming,只是用了一个lambda的形式而已。C++里面的模板匹配才是真正的FP,基
本上就是一个原生态的haskell, 差了点语法糖而已。下面这个帖子就是如何用C++模板
实现monad:
http://bartoszmilewski.com/2011/07/11/monads-in-c/
所谓的functional的精髓我觉得是代码没有side effect,这一点其实只能在编译时做
到。不是说搞一些叫做function或者叫做lambda的东西在语言里就是functional了。
C++那批发明者似乎没有搞FP的,但是他们能从对性能的追求和对语言的直觉搞出来这
么一套系统,不得不说是太牛B了。甩java好几条街。
(这个观点以前在这个版上被批判过,大家需要谨慎对待。)
class |
|
r****r 发帖数: 755 | 12 函数的命名和语法应该清楚地表明函数及其调用者的意图
主要考虑两点:
函数对传入参数的读写权
参数的生命周期
例如
CopyFrom(const T&…) // only for copy
GetNewData(… T& out); // function will write to the argument
Walk(T argp[]); // 明确指出需要数组,会作指针运算,比 Walk(T* argp)语义
清楚;
NoWalk(T* const argp); // 明确函数不作任何指针运算, argp++ 将被compiler视为
非法。 |
|
s*******d 发帖数: 59 | 13 read/write 16/32
读写的操作除了从significant index到storage index的变换不同外,其他都一样。
使用函数指针将这一点抽出来是一种方案,但是还是要为不同的endian写不同的调用
(传入的函数指针变化了)。
如果通过设置Endian flag来判断,又不是很直观。
要是static函数可以是虚的话,就可以BigEndian和LittleEndian都继承Endian,然后
各自
实现自己的变换就好。不过static函数没有虚函数。 |
|
d****n 发帖数: 1637 | 14 C面试题
~~~~~~~~~~~
1.使用 #define 定义一个值为一年的秒数的常量,不考虑润年。
~~~~~~~~~~~
2.使用 #define 定义一个返回两个数中较小的一个的宏。
~~~~~~~~~~~~
3.将变量a定义成如下类型:
1. 有符号整数
2. 双精度浮点数
3. 指向一个有符号整数的指针
4. 一个十个成员的有符号整数数组
5. 一个函数指针,指向的函数返回类型为有符号整数,有一个有符号整数类型的参数
~~~~~~~~~~~~
4.C语言中的static的用处是?
~~~~~~~~~~~~
5. 写出下面函数被调用时的输出。
void foo(void)
{
unsigned int a = 6;
int b = -20;
(a+b > 6) ? puts("> 6") :
puts(" < = 6");
}
~~~~~~~~~~~~
6.写出下面程序的输出
#include
#include
typedef struct
{
char flag;
int value;
}SampleSt... 阅读全帖 |
|
l***t 发帖数: 10 | 15 let me try:
~~~~~~~~~~~
1.使用 #define 定义一个值为一年的秒数的常量,不考虑润年。
#define sec_per_year (60*60*24*365)UL
~~~~~~~~~~~
2.使用 #define 定义一个返回两个数中较小的一个的宏。
#define MIN(a,b) ((a)<=(b)?(a):(b))
~~~~~~~~~~~~
3.将变量a定义成如下类型:
1. 有符号整数
int a;
2. 双精度浮点数
double a;
3. 指向一个有符号整数的指针
int *a;
4. 一个十个成员的有符号整数数组
int a[10];
5. 一个函数指针,指向的函数返回类型为有符号整数,有一个有符号整数类型的参数
int (*a)(int);
~~~~~~~~~~~~
4.C语言中的static的用处是?
~~~~~~~~~~~~
5. 写出下面函数被调用时的输出。
void foo(void)
{
unsigned int a = 6;
int b = -20;
(a+b > 6) ? puts("> 6") :
puts... 阅读全帖 |
|
a*****e 发帖数: 1700 | 16 指针当然是 first class,但是函数指针不能够方便地组合,比如在 Haskell 里面写
f . g 的结果就是一个新函数,换到 C++ 里面就没有这么方便。
新的 C++ 标准提供了 lambda 语法糖,虽然需要手工指定 environment variable 也
不方便,但我觉得比有些其它语言里的方式要好。
总的来说,lambda 已经进入了主流语言的语法,是一件好事。但大部分非函数语言都
无法提供一个高效的实现。
另外,真正明晰的函数闭包语义需要严格区分 reference 和 value,这点上在
javascript, ruby, python, perl, 包括 swift 里面,都做得不好,甚至不如 C++。
最后的结果就是 lambda 和 closure 不好用,主要用途也都是充当一个回调的语法糖
而已。归根结底还是因为语义不明晰,这些语言设计者还不能够理解函数语言的精髓。 |
|
o*****e 发帖数: 379 | 17 只找到remove函数删数,但是参数是文件名。如果一个FILE指针已经打开了文件,如何
获得其打开的文件的名字呢?
或者有什么函数以FILE指针为参数删除文件?
因为是在别人的大project里面改,所以自己定义结构保存指针和文件名的pair会比较
困难。
谢谢。 |
|
s*****k 发帖数: 604 | 18 看到一段代码,一个函数的参数是指针的引用而不是指针,这样做是不是有什么特殊意图
? |
|
D*********G 发帖数: 193 | 19 前一阵面试,被问到Evaluate Reverse Polish Notation.
做完之后,要求设计一个object来完成不同的符号运算,条件是避免if 或者 switch
去check符号,从而提高速度。
当时觉得肯定是要hmap加函数指针。面试官不是很满意,要求设计一个类实现。
不会,主要问题是hmap里面只能放 父函数,调用的时候都是父函数的function。
我的函数指针的方法如下,请大家指点一下如何能用类实现啊
typedef int(*pf)(int, int);
int my_add(int a, int b){ return a + b; }
int my_sub(int a, int b){ return a - b; }
int my_mul(int a, int b){ return a*b; }
int my_div(int a, int b){ return a / b; }
class Solution {
public:
Solution(){
hmap["+"] = my_add, hmap["-"] = my_sub, hm... 阅读全帖 |
|
n****1 发帖数: 1136 | 20 我的原话是这样的:
"任何与FP沾边的语言, 只要function是first class citizen, 甚至包过C语言(有函数
指针), 都完全可以轻松解决dependency injection的问题"
我是把c当成一个极限情况来谈, 也没吹鼓C的opaque方案多么elegant, 只是说连C都可
以做到. 这个不矛盾吧.
如果你再纠结于 函数指针!=opaque指针的话, 咱就真没法继续谈下去了. |
|
f****4 发帖数: 1359 | 21 ac
FN是函数指针的定义,FN返回void,接受一个int参数
f1返回void,接受一个int
f2返回void *,接受一个int
在函数指针赋值的时候,直接取函数名f1和用 &f1是等效果的 |
|
A*********r 发帖数: 564 | 22 declare一个函数指针
int * (func)(); //第一个括号里为函数名
declare一个函数指针数组
int * (func[]) (); |
|
a****s 发帖数: 559 | 23 一般传指针和长度两个参数。
void func(int a[], size_t len)
调用时,数组参数decay成int*指针。
如果要在函数里保留参数的数组特性,
可以传array by reference
void func( int (& a)[10] )
或者传array by pointer
void func( int (* a)[10] )
限制是:数组size需要明确定义。
如果要从函数返回数组,同样
可以return by reference
int (& func())[10]
也可以return by pointer
int (* func())[10]
同样限制,需要明确定义数组size。 |
|
s********r 发帖数: 403 | 24 这个只是是障眼法,
实际上调用的还是已经实例化对象的函数指针,
用函数指针指向某个合法地址,当然可以调用了。
在系统初始化,甚至
typedef int (*init) (int);
*((init*) 0x000f3102)(1) 都可以,只要地址合法。
对于c++,非实例化类的非静态成员函数,不可直接调用。 |
|
f****4 发帖数: 1359 | 25 这里的"&"是用来给成员函数f赋值的
typedef int (Function_pointer::*f)(int n);
void update( int n, f pointer );
myFunc.update( 1, &Function_pointer::next);
在成员函数指针执行的时候必须用对象的 .* 或者是对象指针的 ->* 来调用
也就是说
Function_pointer::f fp1=&Function_pointer::next;
Function_pointer::f fp2=&Function_pointer::before;
Function_pointer::f fp3=&Function_pointer::next_after_next;
都是正确的,只要这些成员函数类型 是 int (...) (int) 即可
但是当你想调用fp1,fp2,fp3必须得
Function_pointer myFunc;
Function_pointer *myFuncpt=&myFunc;
(myFunc.*fp1)(1);
(myFuncpt->*fp2)(... 阅读全帖 |
|
e***r 发帖数: 68 | 26 弄出来了:
1.worker class define&declare一个delegate.
2.然后winform中定义一个函数,绑定到worker class的delegate中
3.每当需要update的时候,worker class调用delegate.
说白了就是把winform中update textbox的函数指针传进worker class,然后update时
worker class调用函数指针对winform进行update.
语法比定义event要简练一些。 |
|
s*****k 发帖数: 604 | 27 用typdef定义
好像
typedef void(*funptr)(void);
和
typedef void(funptr)(void);
两个都可以
也就是说函数和指向函数的指针是一样的.我这样理解对不对啊? |
|
f******y 发帖数: 2971 | 28 第二个定义的是一个函数类型,不是一个指向函数的指针。 |
|
z****e 发帖数: 2024 | 29 不懂这个
char *(*ff(char *(*fb)()))()
{
return fb;
}
char *( *ff(相同类型函数指针) )()//怎么后面接着就给函数定义了?
{
return fb;
}
这个定义是定义什么?难道是函数指针?
{
return fb;
} |
|
T*******x 发帖数: 8565 | 30 这道题我的意图是要定义一个函数ff,
接受一个函数指针作为参数,然后返回一个函数指针。
用typedef表达就是这样的:
typedef char *(*FPtr)();
FPtr ff(FPtr fb)
{
return fb;
}
如果不用typedef,展开之后就是下面的样子。 |
|
X****r 发帖数: 3557 | 31 这几个函数各不相同。1的参数是对3x4的二维int数组的引用,2的参数是
指向3x4的二维int数组的指针,而3的参数是对长度为4的一维数组的指针,
因为函数形参出现T[]类型的时候会作为T*来处理。见C++ 2003 8.3.5
3. ... After determining the type of each parameter,
any parameter of type “array of T” or “function
returning T” is adjusted to be “pointer to T” or
“pointer to function returning T,” respectively.
比如
void func1(int (&array)[3][4]) {}
void func2(int (*array)[3][4]) {}
void func3(int array[3][4]) {}
int main() {
int array[3][4];
func1(array);
func2(&array);
func3(a... 阅读全帖 |
|
t**r 发帖数: 3428 | 32 你确定python没有?tab先搞死一堆入门的。
还有各种丑陋的underscore. 内置函数什么的。
要说恶心python当第二没人敢称第一。
java的dirty little secret也不少,什么函数名大小写 getter setter什么的 对新手
也是挑战。 |
|
m****s 发帖数: 1481 | 33 我需要读取一个数据文件,然后把读出来的数据放到不同的变量里,因为这些变量的长
度不确定,所以都是临时根据长度分配内存,code如下:
... main(){
...
...
int *a,length_a;
double *d,length_d;
char *c,length_c;
FILE *fp;
... 打开文件代码...
...读文件,获取变量a,d,c的长度...
a= new int[length_a];
d= new double[length_d];
c= new char[length_c];
...计算,处理...
delete[] a;
delete[] d;
delete[] c;
}
这种最基本的方法运行没问题。
现在因为我要load的变量很多,所以我想把loading用一个函数来做。如果只有一个变
量,我可以把它的pointer定义在main里面,然后用一个函数读取文件,在函数里
declare一个临时pointer,分配内存,赋值,然后返回这个pointer。
但是如果多个变量的情况怎么做呢?
我先试了把多个变量的指针传递给子函数,在子函数里declare... 阅读全帖 |
|
e****d 发帖数: 333 | 34 指针的引用作为参数的时候,指针的本身的地址也被复制了,不仅仅是指针作指向的地
址。
#include
using namespace std;
void set(double* dp){
dp=new double[10];
for(int i=0;i<10;i++)
dp[i]=i;
}
void setref(double*& dp){
dp=new double[10];
for(int i=0;i<10;i++)
dp[i]=i;
}
int main(){
double* p=0;
setref(p);//换成 set(p); 你在试试看。
for(int i=0;i<10;i++)
cout<
} |
|
b***i 发帖数: 3043 | 35 那你就做个函数专门负责wait,把函数指针传入每个线程。这样,只要他们能找到这个
函数,由这个函数统一负责调用wait,而不是分别两个编译器写不同的代码,你懂了吗
?这个函数是主函数中的。 |
|
f*******y 发帖数: 988 | 36 操,这题很难
隐式无参数函数指针强制静态转换
也许是
隐式无参数函数指针强制重解释转换
更加合理一点
老岳牛逼!
fenwick-west-llp-loses-copyright-jury-trial.html
this
Lynde $
$18m.
by
mouthing Dr |
|
p**********s 发帖数: 115 | 37 原题应该是问typedef定义函数指针,答案前面一个兄弟说了是
typedef int(*myTypeConvert) (int),
这个code是具体说明怎么定义和用函数指针. |
|
w******1 发帖数: 520 | 38 下面的这几个是错的么? 都是什么意思啊? 我觉得三个答案都是错的
about pointer to funciton :
how will a pointer to a pointer to a function will be declared
void (*(*ptr[]));
void *ptr[];
void (**ptr[]) |
|
s********l 发帖数: 998 | 39 1,3括号都不对称 当然错了。。。
2 unknown size |
|
s*****n 发帖数: 162 | 40 How about
int (*(*ptr))();
ptr is a pointer to a pointer that points to a function which returns int |
|
|
w******1 发帖数: 520 | 42 你这个答案, 就是网上给的建议答案。
但是评论中, 没人同意。 所以我就拿不准了。 |
|
w******1 发帖数: 520 | 43 你这个答案, 就是网上给的建议答案。
但是评论中, 没人同意。 所以我就拿不准了。 |
|
|
h********m 发帖数: 116 | 45 想写一个函数,传进去两个地址,把第一个的地址赋给第二个,这样两个指针都指向同
一个address:
int *copy(int *s, int *t){
t = s;
return t;
}
可是我下面的测试,输出1,2,1, 为啥b的值没变啊?但是返回的值c是1,不是说明我的
copy函数里,t指向的地址已经变成s指向的地址了么?
int main(int argc, char **argv) {
int a =1, b =2 ;
int *c = copy(&a, &b);
printf("%d, %d, %d", a, b, *c);
return 0;
} |
|
f****4 发帖数: 1359 | 46 我当然知道通常是怎么做的了。都已经说了obj size太大,需要大量记录对象状态的时
候严重浪费空间,生成销毁instance的时候很慢。
宏是你推崇的Linux kernel开发黄金组合之一C程序员最喜欢的东西,我是很反感这个
特性的。C++里面inline就好了。当然了,这是题外话。
再给你扯个题外话,你做实际的产品的时候,一个功能修改的代码越少,出错的可能越
小;需要测试维护的时间就越小。
你要是做过实际 C 产品而不是个半吊子,就应该看过到类似用函数指针实现dynamic
dispatch的东西;C++里面也可以用成员函数指针array实现类似的东西。 |
|
l*****n 发帖数: 1648 | 47 如果函数参数是二叉树的指针,有没有办法可以把根指针保存下来? |
|
f****n 发帖数: 399 | 48 第一次调用之前存一个全局变量为啥不行?多线程的?
[在 liamsun (维) 的大作中提到:]
:如果函数参数是二叉树的指针,有没有办法可以把根指针保存下来?
:
:........... |
|
|
r********d 发帖数: 23 | 50 不一样。
第一个,你用 funptr x; 是定义了一个指针
第二个,你用 funptr x; 的话,是一个函数声明,和 void x(void); 是一样的 |
|