关于这种如何给指针变量赋值的申明int *test[1] 怎么理解

p=Test::fun()
p=&Test::fun
对成员函数指针的调用
指向公有非静态的成员函数,调用时必须创建一个对象。
class Container{
void print(){
printf(&printf()&);
int main()
void (Container::*p)();
//指明是指向成员函数的指针
p = &Container::
指向静态函数
class Container{
static void print(){
printf(&printf()&);
int main()
void (*p)();
p = &Container::
p = &Test::这个答案才对吧。
p=Test::fun()加上括号就是调用了
答案B是对成员函数的调用,p是函数的返回值。答案C是对一般函数的调用,同样p是返回值。此题选D。对成员函数取地址需要作用域和取地址符
所有的函数若加上(),则表示调用,不加()表示该函数本身
class MyClass {
MyClass(int i = 0) { cout && 1; }
MyClass(const MyClass&x) { cout && 2; }
MyClass& operator=(const MyClass&x) { cout && 3; return* }
~MyClass() { }
void fun(int) {}
int main(void)
void (MyClass::*function)(int);
function = MyClass::
system(&pause&);
至此完成类内部成员函数的函数指针声明,学习到了。
fun()函数本身不就是一个地址吗???求解释不懂
p=&Test::fun 和 p=Test::fun都是正确的。
有括号函数调用 函数名取地址和不取地址都表示地址
不加&可以,加括号不行。
fun的函数名代表的是函数的首地址,用首地址赋值给指针变量是对的,所以D对.
如果像B那样的话,是缺少实参的函数调用.
为什么要加&
对成员函数指针的调用
指向公有非静态的成员函数,调用时必须创建一个对象。
class Container{
void print(){
printf(&printf()&);
int main()
void (Container::*p)();
//指明是指向成员函数的指针
p = &Container::
指向静态函数
class Container{
static void print(){
printf(&printf()&);
int main()
void (*p)();
p = &Container::
感谢@revivedSuN
函数名相当于函数的地址。
这道题你会答吗?花几分钟告诉大家答案吧!
扫描二维码,关注牛客网
下载牛客APP,随时随地刷题
京ICP备号-4
扫一扫,把题目装进口袋指针到成员运算符:.* 和 -&*
指针到成员运算符:.* 和 -&*
指针到成员运算符:.* 和 -&*
Visual Studio 2015
若要了解有关 Visual Studio 2017 RC 的最新文档,请参阅 。
expression .* expression
expression –&* expression
指向成员的指针运算符(.* 和 –&*)返回表达式左侧上指定的对象的特定类成员的值。右侧必须指定该类的成员。下面的示例演示如何使用这些运算符:
// expre_Expressions_with_Pointer_Member_Operators.cpp
// compile with: /EHsc
#include &iostream&
class Testpm {
void m_func1() { cout && "m_func1\n"; }
// Define derived types pmfn and pmd.
// These types are pointers to members m_func1() and
// m_num, respectively.
void (Testpm::*pmfn)() = &Testpm::m_func1;
int Testpm::*pmd = &Testpm::m_
int main() {
Testpm *pTestpm = new T
// Access the member function
(ATestpm.*pmfn)();
(pTestpm-&*pmfn)();
// Parentheses required since * binds
// less tightly than the function call.
// Access the member data
ATestpm.*pmd = 1;
pTestpm-&*pmd = 2;
&& ATestpm.*pmd && endl
&& pTestpm-&*pmd &&
在前面的示例中,指向成员的指针 pmfn 用于调用成员函数 m_func1。
另一个指向成员的指针 pmd 用于访问 m_num 成员。二元运算符 .* 将其第一操作数(必须是类类型的对象)与其第二操作数(必须是指向成员的指针类型)组合在一起。二元运算符 –&* 将其第一操作数(必须是指向类类型的对象的指针)与其第二操作数(必须是指向成员的指针类型)组合在一起。在包含 .* 运算符的表达式中,第一操作数必须是类类型且可访问,而指向第二操作数中指定的成员的指针或可访问类型的成员的指针明确从该类派生并且可供该类访问。在包含 –&* 运算符的表达方式中,第一操作数必须是第二操作数中指定的类型的“指向类类型的指针”或明确地从该类派生的类型。考虑以下类和程序段:
// expre_Expressions_with_Pointer_Member_Operators2.cpp
// C2440 expected
class BaseClass {
BaseClass(); // Base class constructor.
void Func1();
// Declare a pointer to member function Func1.
void (BaseClass::*pmfnFunc1)() = &BaseClass::Func1;
class Derived : public BaseClass {
Derived();
// Derived class constructor.
void Func2();
// Declare a pointer to member function Func2.
void (Derived::*pmfnFunc2)() = &Derived::Func2;
int main() {
BaseClass AB
Derived AD
(ABase.*pmfnFunc1)();
// OK: defined for BaseClass.
(ABase.*pmfnFunc2)();
// Error: cannot use base class to
// access pointers to members of
// derived classes.
(ADerived.*pmfnFunc1)();
// OK: Derived is unambiguously
// derived from BaseClass.
(ADerived.*pmfnFunc2)();
// OK: defined for Derived.
指向成员的指针运算符 .* 或 –&* 的结果是在指向成员的指针的声明中指定的类型的对象或函数。
因此,在前面的示例中,表达式 ADerived.*pmfnFunc1() 的结果是指向返回 void 的函数的指针。
如果第二操作数是左值,则此结果为左值。 说明
如果某个指向成员的指针运算符的结果是函数,则该结果只能用作函数调用运算符的操作数。
此页面有帮助吗?
更多反馈?
1500 个剩余字符
我们非常感谢您的反馈。C/C++中函数指针的含义
  函数指针同样是可以作为参数传递给函数的,下面我们看个例子,仔细阅读你将会发现它的用处,稍加推理可以很方便我们进行一些复杂的编程工作。//-------------------该例以上一个例子作为基础稍加了修改-----------------------------& #include&&iostream&&&& #include&&string&&&& using&namespace&&&& &&& int&test(int);&&& & int&test2(int&(*ra)(int),int);& & void&main(int&argc,char*&argv[])&&&&& {&&& &&&&cout&&test&&& &&&&typedef&int&(*fp)(int);&&& &&&&fp&& &&&&fpi=//fpi赋予test&函数的内存地址& & &&&&cout&&test2(fpi,1)&&//这里调用test2函数的时候,这里把fpi所存储的函数地址(test的函数地址)传递了给test2的第一个形参& &&&&cin.get();& }&&& &&& int&test(int&a)& {&&& &&&&return&a-1;& }& & int&test2(int&(*ra)(int),int&b)//这里定义了一个名字为ra的函数指针& {& &&&&int&c=ra(10)+b;//在调用之后,ra已经指向fpi所指向的函数地址即test函数& &&&&return&c;& }   利用函数指针,我们可以构成指针数组,更明确点的说法是构成指向函数的指针数组,这么说可能就容易理解的多了。#include&&iostream&&&& #include&&string&&&& using&namespace&& & void&t1(){cout&&"test1";}& void&t2(){cout&&"test2";}& void&t3(){cout&&"test3";}& void&main(int&argc,char*&argv[])&&&&& {& &&&&void*&a[]={t1,t2,t3};& &&&&cout&&"比较t1()的内存地址和数组a[0]所存储的地址是否一致"&&t1&&"|"&&a[0]&&& & &&&&cout&&a[0]();//错误!指针数组是不能利用数组下标操作调用函数的& & &&&&typedef&void&(*fp)();//自定义一个函数指针类型& &&&&fp&b[]={t1,t2,t3};&//利用自定义类型fp把b[]定义趁一个指向函数的指针数组& &&&&b[0]();//现在利用指向函数的指针数组进行下标操作就可以进行函数的间接调用了;& &&&&cin.get();& }   仔细看上面的例子可能不用我多说大家也会知道是怎么一会事情了,最后我们做一个重点小结,只要记住这一点,对于理解利用函数指针构成数组进行函数间接调用就很容易了! void* a[]={t1,t2,t3}; cout&&"比较t1()的内存地址和数组a[0]所存储的地址是否一致"&&t1&&"|"&&a[0]&& cout&&a[0]();//错误!指针数组是不能利用数组下标操作调用函数的   上面的这一小段中的错误行,为什么不能这么调用呢?   前一篇教程我们已经说的很清楚了,不过在这里我们还是复习一下概念,指针数组元素所保存的只是一个内存地址,既然只是个内存地址就不可能进行a[0]()这样地址带括号的操作,而函数指针不同它是一个例外,函数指针只所以这么叫它就是因为它是指向函数指向内存的代码区的指针,它被系统授予允许与()括号操作的权利,进行间接的函数调用,既然函数指针允许这么操作,那么被定义成函数指针的数组就一定是可以一样的操作的。
键盘也能翻页,试试“← →”键
最新资讯离线随时看
聊天吐槽赢奖品
相关软件:
大小:1.93 MB
授权:免费
大小:62.51 MB
授权:免费详解C语言指针与常量的关系
点击关注异步图书,置顶公众号
每天与你分享IT好书 技术干货 职场知识
常量指针概述
前面讲过 const 前置作用于变量可创建符号常量
1const int test = 10.5;
也可以用 #define 宏指令实现。但 const 还可以创建数组常量、指针常量、指向常量的指针
1#define test 10.52const int test[2] = {1, 2};
在此后的代码如果尝试修改 test 数组常量,编译将无法继续。
1test[0] = 5;
指向常量的指针不能用于修改数值
1double test[5]{1.5, 2.5, 3.5, 4.5, 5.5};2const double *p =//声明了个指向double的指针,指针指向 test 数值开始,这是允许赋值的
第二行代码是 p 指向 const double 的指针,这样就无法使用 p 来修改它所指向的值
1p = 10.5;//非法操作2p[2] = 10.5//非法操作
无论使用数组还是指针符号的方式来操作指针以求更变被指向的数据的值的方式都是不可取的。
但是如果这个指针附近有其他变量空间,可以通过这个常量指针指向其他地址。
1p++;//让指针指向其他开辟的地址,这是允许的
此处输出将是 2.5;
函数的常量指针参数
通常把指向常量的指针作为函数的形式参量,用于表明函数不会通过指针修改数据,例如函数 test()的原型声明
1test(const double *p) 常量指针赋值的问题
关于指针赋值和 const 需要注意一些规则。比如,将常量或者非常量的数据地址赋予指针是合法的,你可以获取或者指向它,但是不能它的修改数据。
1int test[2] = {0, 5};2const int p =//该常量指针指向了 test 数组首元素,是合法的。
p++;//此时输出你会发现任然能够正常编译,但是仔细查看后,输出的是数组的第二个元素(值 5),因为 p 先取出了 p 指针指向元素元素的值,然后将指针本身自增了 1 ,自增 1 移动了一个数据单位,指针指向了现在这个元素的下一个元素(如果存在的话就会输出正常值,不存在,这将是一个垃圾值),所以指针并没有改变指向元素的数据,依然是常量指针状态。(p)++;//此时你更改了数据,你先取出指针 p 指向的值,再把这个值加上了 1(而不是一个数据单位),但是这编译将不会通过,因为是不合法的,你使用的是常量指针指向这个值。
一句话总结,常量指针,允许被赋值,但是不能更改数据!
常量数据赋值给普通指针的问题
然而常量指针可以指向常量或者非常量数据,只是不能修改。但是常量的数据是不能被指针所指向的,比如下面这个例子
1const int test = 5; //test 是 int 类型的常量数据2int p =//这是不被允许的,不能把普通指针不能指向常量数据,否则你就能修改常量的数据了,这样就丧失了常量存在的意义。3const int p =//但是如果你这样,用一个常量指针,指向一个常量的数据,是可行的。 常量和函数参量搭配使用
在函数参数定义(声明)中,使用 const 可以保护数据,防止数据被修改。并且可以让你使用其他函数中声明为 const 的数据(如果不在函数中使用 const 来修饰的指针(即普通指针),那么普通指针是无法指向常量数据的(出错),只有常量指针才能指向常量或非常量数据),但是你要不打算用指针来作为形参,而是用普通变量或者常量类型来接收数据,也是可行的。
注意,这是指针常量,而不是上面说的常量指针,这是两个内容,这可能有点绕口,但是先看下面这个例子。之前我们用 const 来修饰一个指针整体,而不是指针本身,我们可以任意的再把指针指向其他的地址,可以对这个指针进行增量减量数据单位以指向下一个元素地址,,可改地址只是不能修改其指向元素的数据,所以这是一个常量指针。从中文语义分析来说,常量是形容词,指针是名词,以指针为中心的一个偏正结构短语(偏和正,主次关系)。这样看,常量指针本质是指针,常量修饰它,表示这个指针乃是一个指向常量的指针(变量),指针指向的对象是常量,那么这个对象不能被更改。( 此处内容自网络)常量指针,是常量作为主语,指针修饰常量。所以常量指针,指针本身不是常量。而指针常量,指针为主语,是常量修饰指针,所以指针常量,指针本身是常量。 有点拗口,多读几遍!
指针常量是什么
用关键字 const 修饰本体为指针本身时,我们能保护指针指向的元素地址不被更改,而内容可被更改。这正好这和常量指针恰恰相反,刚好也说明了常量的对象不一样。这两个之间的区别就在于 const 的位置,比如下面这个例子。
1int test[2] = {0, 5};2const int p =//常量指针 能够改变地址,但无法改变数据3int const p =//常量指针 这两个常量指针的 const 均放置于指针的外面,而不是内部4int * const p =//指针常量 仍然可以修改被指向的变量的值,但是无法改变地址,只能是最初赋给指针的地址。 常量指针的多种写法
注意:以上可见,常量指针有两种写法,分别是 const 前置到类型声明,另一个是 const 放置在类型声明后,但未进入指针声明。本来以为这两个写法是存在歧义,有优先级差异。但是经过实际编译器优化后,转为汇编分析比对。在优化后,或者编译后,两个语句为等同语句,并无差异,均为声明指针常量。如图:
既不可改变地址也不可改变数据的指针
有的情况下要保证数据不可变动,这包括了指针指向地址和指向地址的内容都不可更改。那么我们只需要结合常量指针和指针常量即可。用两个 const 来构造声明指针,这个指针既不可以更改所指向的地址,也不可以更改被指向地址所存储的数据。确保了数据的安全。比如:
1int test[2] = {0, 5};2int const * const p =3cosnt int * const p = 最后的安利
异步社区是一个有氛围并且资源丰富的IT专业图书社区,在这里可以读到最新、最热的IT类图书!我想要社区的《操作系统真象还原》
1int test[2] = {0, 5};2int const * const p =3cosnt int * const p = 最后的安利
异步社区是一个有氛围并且资源丰富的IT专业图书社区,在这里可以读到最新、最热的IT类图书!我想要社区的《操作系统真象还原》
2018年5月新书书单
2018年4月新书书单
异步图书最全Python书单
一份程序员必备的算法书单
第一本Python神经网络编程图书
长按二维码,可以关注我们哟
每天与你分享IT好文。
在“异步图书”后台回复“关注”,即可免费获得2000门在线视频课程;推荐朋友关注根据提示获取赠书链接,免费得异步e读版图书一本。赶紧来参加哦!
责任编辑:
声明:该文观点仅代表作者本人,搜狐号系信息发布平台,搜狐仅提供信息存储空间服务。
今日搜狐热点

我要回帖

更多关于 指针怎么指向数组 的文章

 

随机推荐