C++深度解析教程笔记4
- 第7课 - 函数参数的扩展
- 实验-默认参数
- 实验-从右提供的默认参数
- 实验-默认值与占位参数结合
- 小结
- 第8课 - 函数重载分析(上)
- 实验-函数重载
- 实验-有歧义的重载
- 实验-重载函数是同一函数吗
- 查看vs2010的obj文件的符号表
- 小结
- 第9课 - 函数重载分析(下)
- 实验-重载与指针
- 实验-Cpp调用C函数
- 生成o文件,cpp调用
- 增加extern "C"{}
- C编译器不认识 extern "C"
- 优化代码
- 实验-extern "C"内部不能存在重载
- 函数重载在符号表里是不同的标识
- extern “C”内部有重载,报错
- 小结
本文学习自狄泰软件学院 唐佐林老师的 C++深度解析教程,图片全部来源于课程PPT,仅用于个人学习记录
第7课 - 函数参数的扩展
实验-默认参数
#include <stdio.h>int mul(int x = 0);int main(int argc, char *argv[])
{printf("%d\n", mul());printf("%d\n", mul(-1));printf("%d\n", mul(2));return 0;
}int mul(int x)
{return x * x;
}
/*
output:
0
1
4*/
实验-从右提供的默认参数
#include <stdio.h>int add(int x, int y = 0, int z = 0);int main(int argc, char *argv[])
{printf("%d\n", add(1));printf("%d\n", add(1, 2));printf("%d\n", add(1, 2, 3));return 0;
}int add(int x, int y, int z)
{return x + y + z;
}
/*
1
3
6*/
//C代码
#include <stdio.h>
//void fun()//case1
void fun(void)//case2
{
}int main(int argc, char *argv[])
{//fun(1, 2);//case1编译通过了fun(1, 2);//case2 error: too many arguments to function 'fun'return 0;
}
//cpp
#include <stdio.h>
void fun()//case1
//void fun(void)//case2
{
}int main(int argc, char *argv[])
{fun(1, 2);//case1 error: too many arguments to function 'fun'//fun(1, 2);//case2 error: too many arguments to function 'fun'return 0;
}#include <stdio.h>
void fun(int,int)//添加占位参数{
}int main(int argc, char *argv[])
{fun(1, 2);// successreturn 0;
}
实验-默认值与占位参数结合
//C
#include <stdio.h>void func()
{
}int main(int argc, char *argv[])
{func();//OKfunc(2, 3);//OKreturn 0;
}
//cpp#include <stdio.h>void func(int =0, int = 0)
{
}int main(int argc, char *argv[])
{func();//OKfunc(2, 3);//OKreturn 0;
}
小结
第8课 - 函数重载分析(上)
实验-函数重载
#include <stdio.h>
#include <string.h>int func(int x)
{return x;
}int func(int a, int b)
{return a + b;
}int func(const char* s)
{return strlen(s);
}int main(int argc, char *argv[])
{printf("%d\n", func(3));//3printf("%d\n", func(4, 5));//9printf("%d\n", func("D.T.Software"));//12return 0;
}
实验-有歧义的重载
#include <stdio.h>int func(int a, int b, int c = 0)
{return a * b * c;
}int func(int a, int b)
{return a + b;
}int main(int argc, char *argv[])
{int c = func(1, 2);//error: call of overloaded 'func(int, int)' is ambiguousreturn 0;
}
实验-重载函数是同一函数吗
#include <stdio.h>int add(int a, int b) // int(int, int)
{return a + b;
}int add(int a, int b, int c) // int(int, int, int)
{return a + b + c;
}int main()
{printf("%p\n", (int(*)(int, int))add); printf("%p\n", (int(*)(int, int, int))add); return 0;
}
//cmd
E:\test>g++ 8-3.cppE:\test>a
0000000000401550
0000000000401564
查看vs2010的obj文件的符号表
C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC>dumpbin /symbols "D:\Users\Documents\Visual Studio 2010\Projects\test\helloworld\Debug\test.obj"
Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.Dump of file D:\Users\Documents\Visual Studio 2010\Projects\test\helloworld\Debug\test.objFile Type: COFF OBJECTCOFF SYMBOL TABLE
000 00AB9D1B ABS notype Static | @comp.id
001 00000001 ABS notype Static | @feat.00
002 00000000 SECT1 notype Static | .drectveSection length 30, #relocs 0, #linenums 0, checksum 0
004 00000000 SECT2 notype Static | .debug$SSection length E74, #relocs 13, #linenums 0, checksum 0
006 00000000 SECT3 notype Static | .rdataSection length 8, #relocs 0, #linenums 0, checksum C59740A9
008 00000000 SECT3 notype Static | $SG3864
009 00000004 SECT3 notype Static | $SG3869
00A 00000000 SECT4 notype Static | .textSection length 68, #relocs 9, #linenums 0, checksum F4126B23
00C 00000000 SECT4 notype () External | ?add@@YAHHH@Z (int __cdecl add(int,int))
00D 00000000 SECT5 notype Static | .rtc$TMZSection length 4, #relocs 1, #linenums 0, checksum 0, selection 2 (pick any)
00F 00000000 SECT5 notype Static | __RTC_Shutdown.rtc$TMZ
010 00000000 UNDEF notype () External | __RTC_Shutdown
011 00000000 SECT6 notype Static | .rtc$IMZSection length 4, #relocs 1, #linenums 0, checksum 0, selection 2 (pick any)
013 00000000 SECT6 notype Static | __RTC_InitBase.rtc$IMZ
014 00000000 UNDEF notype () External | __RTC_InitBase
015 00000010 SECT4 notype () External | ?add@@YAHHHH@Z (int __cdecl add(int,int,int))
016 00000020 SECT4 notype () External | _main
017 00000000 UNDEF notype External | __imp__printf
018 00000000 UNDEF notype () External | __RTC_CheckEsp
019 00000000 SECT7 notype Static | .debug$TSection length 6C, #relocs 0, #linenums 0, checksum 0String Table Size = 0x8A bytesSummaryE74 .debug$S6C .debug$T30 .drectve8 .rdata4 .rtc$IMZ4 .rtc$TMZ68 .text//符号表
// 00C 00000000 SECT4 notype () External | ?add@@YAHHH@Z (int __cdecl add(int,int))
// 015 00000010 SECT4 notype () External | ?add@@YAHHHH@Z (int __cdecl add(int,int,int))
小结
第9课 - 函数重载分析(下)
实验-重载与指针
#include <stdio.h>
#include <string.h>int func(int x)//case1
{return x;
}int func(int a, int b)
{return a + b;
}int func(const char* s)
{return strlen(s);
}typedef int(*PFUNC)(int a);//只跟case1的类型一致int main(int argc, char *argv[])
{int c = 0;PFUNC p = func;c = p(1); printf("c = %d\n", c);return 0;
}
/*
E:\test>g++ 9-1.cppE:\test>a
c = 1
*/
实验-Cpp调用C函数
//add.h
int add(int a, int b);
//add.c
#include "add.h"
int add(int a, int b)
{return a + b;
}
//main0.cpp
#include <stdio.h>
#include "add.h"int main()
{int c = add(1, 2);printf("c = %d\n", c);return 0;
}
生成o文件,cpp调用
//cmd
E:\test\9-2>gcc -c add.c -o add.oE:\test\9-2>g++ main0.cpp add.o
C:\Users\cyz1994\AppData\Local\Temp\ccaFXqUM.o:main0.cpp:(.text+0x18): undefined reference to `add(int, int)'
collect2.exe: error: ld returned 1 exit statusE:\test\9-2>nm add.o //查看符号表
0000000000000000 b .bss
0000000000000000 d .data
0000000000000000 p .pdata
0000000000000000 r .rdata$zzz
0000000000000000 t .text
0000000000000000 r .xdata
0000000000000000 T add
增加extern “C”{}
C编译器不认识 extern “C”
E:\test\9-2>gcc main0.c
main0.c:4:8: error: expected identifier or '(' before string constantextern "C"{^~~
优化代码
#include <stdio.h>#ifdef __cplusplus
extern "C" {
#endif#include "add.h"#ifdef __cplusplus
}
#endifint main()
{int c = add(1, 2);printf("c = %d\n", c);return 0;
}
实验-extern "C"内部不能存在重载
函数重载在符号表里是不同的标识
extern “C”内部有重载,报错
小结