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);// success
return 0;
}
实验-默认值与占位参数结合
//C
#include <stdio.h>
void func()
{
}
int main(int argc, char *argv[])
{
func();//OK
func(2, 3);//OK
return 0;
}
//cpp
#include <stdio.h>
void func(int =0, int = 0)
{
}
int main(int argc, char *argv[])
{
func();//OK
func(2, 3);//OK
return 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));//3
printf("%d\n", func(4, 5));//9
printf("%d\n", func("D.T.Software"));//12
return 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 ambiguous
return 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.cpp
E:\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.obj
File Type: COFF OBJECT
COFF SYMBOL TABLE
000 00AB9D1B ABS notype Static | @comp.id
001 00000001 ABS notype Static | @feat.00
002 00000000 SECT1 notype Static | .drectve
Section length 30, #relocs 0, #linenums 0, checksum 0
004 00000000 SECT2 notype Static | .debug$S
Section length E74, #relocs 13, #linenums 0, checksum 0
006 00000000 SECT3 notype Static | .rdata
Section 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 | .text
Section 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$TMZ
Section 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$IMZ
Section 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$T
Section length 6C, #relocs 0, #linenums 0, checksum 0
String Table Size = 0x8A bytes
Summary
E74 .debug$S
6C .debug$T
30 .drectve
8 .rdata
4 .rtc$IMZ
4 .rtc$TMZ
68 .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.cpp
E:\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.o
E:\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 status
E:\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 constant
extern "C"{
^~~
优化代码
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "add.h"
#ifdef __cplusplus
}
#endif
int main()
{
int c = add(1, 2);
printf("c = %d\n", c);
return 0;
}
实验-extern "C"内部不能存在重载
函数重载在符号表里是不同的标识
extern “C”内部有重载,报错
小结