cpp——与c之不同——指针

来源:互联网 发布:mysql ocp认证费用 编辑:程序博客网 时间:2024/05/16 10:19

void*

c

void void_pointer(){    int i = 5;    void* pv = &i;    int* pi = pv;        printf("sizeof(void) = %ld\n", sizeof(void));        printf("pv = %p, pi = %p, *pi = %d\n", pv, pi, *pi);        pv++;    printf("pv = %p\n", pv);    pv += 5;    printf("pv = %p\n", pv);        *pv;    //i = *pv;}
output:
sizeof(void) = 1pv = 0x7fff5fbff834, pi = 0x7fff5fbff834, *pi = 5pv = 0x7fff5fbff835pv = 0x7fff5fbff83a
总结:
  • void指针基础类型为void,而void类型字长为1,因此void指针单位偏移地址为1,因此void指针支持算术运算
  • 支持对void*指针使用*运算(不支持直接使用void类型,因此没有void类型对象)
  • 支持void*类型指针转其他类型指针

c++

void void_pointer(){    int i = 5;    void* pv = &i;    //int* pi = pv;        //printf("sizeof(void) = %ld\n", sizeof(void));        //printf("pv = %p, pi = %p, *pi = %d\n", pv, pi, *pi);        //pv++;    printf("pv = %p\n", pv);    //pv += 5;    printf("pv = %p\n", pv);        //*pv;    //i = *pv;}
总结:
  • void指针基础类型为void,而void类型字长未定义,因此void指针单位偏移地址未定义,因此void指针不支持算术运算
  • 不支持对void*指针使用*运算,因为void字长未定义
  • 不支持void*类型指针转其他类型指针

函数指针

c

c不支持函数重载,因此函数名唯一确定函数,因此如果函数声明omit形参,编译时函数调用会ignore形参检查(形参个数和类型),如果函数运行异常,运行期才能发现,但如果没有omit形参,编译时函数调用会做形参检查(形参个数和类型)
假如feed.c中定义如下函数
void feed(int rice, int meat){    printf("feed rice %d and meat %d\n", rice, meat);}
在main.c中进行如下函数调用
void feed();void call_feed(){    feed();    feed(5);    feed(5, 8);    feed(5, 8, 58);}
output:
feed rice 1 and meat 1606416504feed rice 5 and meat 73832feed rice 5 and meat 8feed rice 5 and meat 8
注:feed(),feed(5)实参缺失,函数运行异常,feed(5, 8, 58)传递了多余实参
因为c不支持函数重载,feed()调用link时search _sub_feed_(不包含形参)目标代码入口,而void feed(int rice, int meat)函数定义在目标代码中入口地址为_sub_feed_(不包含形参),因此link时能search到,正确link
函数这个特性相应扩展到了函数指针类型,如果函数指针类型omit形参,编译时函数指针类型ignore形参检查(形参个数和类型),如果函数指针类型运行异常,运行期才能发现,但如果没有omit形参,编译时函数指针类型会做形参检查(形参个数和类型),因此omit形参的函数指针类型(无参函数指针类型)与没有omit形参的函数指针类型(含参函数指针类型)可相互转换(函数返回类型必须一致)
void feed0(){    printf("feed none\n");}void feed1(int rice){    printf("feed rice %d\n", rice);}void feed2(int rice, int meat){    printf("feed rice %d and meat %d\n", rice, meat);}void feed3(int rice, int meat, int fruit){    printf("feed rice %d and meat %d and fruit %d\n", rice, meat, fruit);}typedef void (*PFeed0)();typedef void (*PFeed1)(int);typedef void (*PFeed2)(int, int);typedef void (*PFeed3)(int, int, int);void fun_pointer(){    PFeed0 pfeed0 = feed0;    PFeed1 pfeed1 = feed1;    PFeed2 pfeed2 = feed2;    PFeed3 pfeed3 = feed3;        pfeed0 = feed1;    pfeed0 = feed2;    pfeed0 = feed3;        pfeed0();    pfeed0(5);    pfeed0(5, 8);    pfeed0(5, 8, 58);        pfeed1 = feed0;    pfeed2 = feed0;    pfeed3 = feed0;        //pfeed1();    pfeed1(5);    //pfeed2();    pfeed2(5, 8);    //pfeed3();    pfeed3(5, 8, 58);        //pfeed1 = feed2;    //pfeed2 = feed1;        //pfeed1 = feed3;    //pfeed3 = feed1;        //pfeed2 = feed3;    //pfeed3 = feed2;}
output:
feed rice 0 and meat 0 and fruit 0feed rice 5 and meat 0 and fruit 0feed rice 5 and meat 8 and fruit 0feed rice 5 and meat 8 and fruit 58feed nonefeed nonefeed none
注:通过omit形参的函数指针类型(无参函数指针类型)调用函数时,ignore形参检查(形参个数和类型)

c++

c++支持函数重载,因此函数名+形参(形参个数和类型)唯一确定函数,omit形参的函数声明仅仅表示无参函数声明,没有多余其他含义,编译时函数调用无论如何都会做形参检查(形参个数和类型)
假如feed.cpp中定义如下函数
void feed(int rice, int meat){    printf("feed rice %d and meat %d\n", rice, meat);}
在main.cpp中进行如下函数调用
void feed();void call_feed(){    feed();    //feed(5);    //feed(5, 8);    //feed(5, 8, 58);}
注:编译时,feed(5),feed(5, 8),feed(5, 8, 58)与函数声明void feed()形参不匹配,而feed()尽管与函数声明void feed()匹配,但link error
因为c++支持函数重载,feed()调用link时search _sub_feed_目标代码入口(包含形参,表示无参),而void feed(int rice, int meat)函数定义在目标代码中入口地址为_sub_feed_int_int_(包含形参,两个形参int,int),因此link时search不到,link error
函数这个特性相应扩展到了函数指针类型,因此c++支持函数重载,因此omit形参的函数指针类型仅仅表示无参函数指针类型,没有多余其他含义,编译时函数指针类型无论如何都会做形参检查(形参个数和类型),因此omit形参的函数指针类型(无参函数指针类型)与没有omit形参的函数指针类型(含参函数指针类型)不可相互转换(函数返回类型必须一致)
void feed0(){    printf("feed none\n");}void feed1(int rice){    printf("feed rice %d\n", rice);}void feed2(int rice, int meat){    printf("feed rice %d and meat %d\n", rice, meat);}void feed3(int rice, int meat, int fruit){    printf("feed rice %d and meat %d and fruit %d\n", rice, meat, fruit);}typedef void (*PFeed0)();typedef void (*PFeed1)(int);typedef void (*PFeed2)(int, int);typedef void (*PFeed3)(int, int, int);void fun_pointer(){    PFeed0 pfeed0 = feed0;    PFeed1 pfeed1 = feed1;    PFeed2 pfeed2 = feed2;    PFeed3 pfeed3 = feed3;        //pfeed0 = feed1;    //pfeed0 = feed2;    //pfeed0 = feed3;        pfeed0();    //pfeed0(5);    //pfeed0(5, 8);    //pfeed0(5, 8, 58);        //pfeed1 = feed0;    //pfeed2 = feed0;    //pfeed3 = feed0;        //pfeed1();    pfeed1(5);    //pfeed2();    pfeed2(5, 8);    //pfeed3();    pfeed3(5, 8, 58);        //pfeed1 = feed2;    //pfeed2 = feed1;        //pfeed1 = feed3;    //pfeed3 = feed1;        //pfeed2 = feed3;    //pfeed3 = feed2;}
output:
feed nonefeed rice 5feed rice 5 and meat 8feed rice 5 and meat 8 and fruit 58
0 0
原创粉丝点击