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
- cpp——与c之不同——指针
- cpp——与c之不同——enum
- cpp——与c之不同——函数
- cpp——与c之不同——初始化
- cpp——与c比较之不同——函数 static const
- cpp——与c之不同——内置类型
- cpp——与c之不同——数组 字符串
- cpp——与c之不同——struct union
- cpp——与c之不同——static const
- C与指针——与谭浩强不同的C
- java——与c比较之不同——指针 引用 struct union 数组
- C++与C不同之二——引用
- java——与c比较之不同(三)
- CPP与C的不同与同
- C与CPP的同与不同
- C语言深度剖析之—指针与内存地址(函数指针,普通指针,指针数组,数组的指针,指针的指针)
- C语言深度剖析之—指针与内存地址(函数指针,普通指针,指针数组,数组的指针,指针的指针)
- C语言深度剖析之—指针与内存地址(函数指针,普通指针,指针数组,数组的指针,指针的指针)
- UNITY新手小游戏
- leetCode练习(134)(
- 计算FLT_MAX的整数位长度
- 利用Lambda解决蓝桥杯【消除尾一】问题
- 练习项目之---jdbc对面的女孩看过来
- cpp——与c之不同——指针
- linux下的基本操作02(文件相关命令)
- javaee 学习路线
- 排序算法(冒泡、选择、插入)
- 手机信息页面设置
- 论文格式的排版
- PAT1028人口普查
- MongoDB安装
- Linux 网络编程——并发服务器的三种实现模型