【C++碎碎念】函数

目录

1、分文件编写

2、防止头文件重复包含

3、指针变量作为函数的参数

4、指针作为函数返回值类型

5、函数和数组

6、函数和字符串

7、递归

8、引用作为函数参数

9、内联函数inline

10、函数重载

11、extern "C"的用法


1、分文件编写

在C++开发的项目中,通常都是需要多文件编写的。

分文件编写的思想:函数的定义在单独的.cpp文件中,函数的声明在对应的.h中

//math.h
#ifndef _MATH_H_
#define _MATH_H_

int add(int,int);
int sub(int,int);
int div(int,int);

#endif
//math.cpp
#include "math.h"
int add(int a,int b)
{
    return a+b;
}
int sub(int a,int b)
{
    return a-b;
}
int div(int a,int b)
{
    return a/b;
}
//main.cpp
#include <iostream>
#include "math.h"
using namespace std;
int main()
{
    int x=23;
    int y=12;
    cout<<"x+y="<<add(x,y)<<endl;
    return 0;
}

linux中执行命令:g++ *.cpp,然后回车就会出现一个a.out的可执行文件,紧接着输入命令./a.out就可以输出结果。

2、防止头文件重复包含

由于在不知情的情况下,很有可能会将头文件重复包含,重复包含的坏处就是如果包含的文件中有定义的变量,那么就会报“重复定义”的错误。

C++重复包含头文件,编译器拷贝和扫描需要耗费时间,降低效率;

那么怎么解决这个问题呢?

使用#ifndef #define #endif

举例说一下他们的意思:

#ifndef _FUNC_H_  //_FUNC_H_没有定义过了吗?
#define _FUNC_H_  //如果没有,则开始定义

要写的内容


#endif   //结束标志位

3、指针变量作为函数的参数

1)通过普通变量在函数内部修改普通变量的值,是不能修改的

void func(int num)
{
    num=100;
    
}
int main()
{
    int a=9;
    func(a);
    cout<<"a="<<a<<endl;//9

}

2)如果想要通过函数内部修改外部变量的值,需要传递外部变量的地址

void func(int *p)
{
    *p=100;
}
int main()
{
    int a=10;
    func(&a);//地址指向了p
    cout<<"a="<<a<<endl;//100

    return 0;

}

4、指针作为函数返回值类型

不要返回局部变量的地址,因为局部变量当函数调用完毕以后会自动释放内存。

int num=0;//定义全局变量
int *get()
{
    return &num;
}

//*****************************************************

int *get1()
{
    int a=10;  //定义局部变量
    return &a;
}
int main()
{
    cout<<"*get1()="<<*get1()<<endl;
    cout<<"*get1()="<<*get1()<<endl;
    cout<<"*get1()="<<*get1()<<endl;
}

 

通过运行就会看出,定义局部变量就会提醒错误。 

 执行时还会报段错误

5、函数和数组

编译器会将数组参数转成  指针类型的变量,用于接收数组首元素的地址。

void func(int arr[])  //优化成  int *p
{
    cout<<sizeof(arr)<<endl;
}

6、函数和字符串

字符串的三种表示形式:char数组、字符串常量、char *

int charCount(const char* str,char c)
{

    cout<<"*str="<<*str<<endl;//只输出字符串的第一个字符
    cout<<"str="<<str<<endl;//输出字符串的全部字符
    int count=0;//记录c出现的次数

    while(*str)
    {
        if(*str == c)
        {
            count++;
        }
            str++;
    }
    return count;
}
int main()
{
    char arr[15] = "lllhelllo";
    const char* str="lllhelllo";

    int n1=strlen(arr);//专门记录字符串的长度 9
    int n2=strlen(str);//9

    int count=charCount(arr,'l');
    cout<<count<<endl;

}

7、递归

函数定义中调用函数本身,称为递归

解决思路:拆分和合并

注意:递归一定要有出口,不然会产生死递归,stack overflow栈溢出

还有递归的次数不能过多

int func(int n)
{
    if(n==1)
    return n;
    else
    return n*func(n-1);
}
int main()
{
    int n=func(5);
    return n;
}

8、引用作为函数参数

函数参数传递的方式有3种:1、值传递        2、地址传递       3、引用传递

1、按值传递
void value(int x,int y)
{
    int temp=x;
    x=y;
    y=temp;
}
2、按地址传递
void pointer(int *x,int *y)
{
    int temp=*x;
    *x=*y;
    *y=temp;
}
3、按引用传递
void reference(int &x,int &y)
{
    int temp=x;
    x=y;
    y=temp;
}
int main()
{
    int a=20;
    int b=30;
    //value(a,b);
    //pointer(&a,&b);
    //reference(a,b);
    cout<<"a="<<a<<endl;
    cout<<"b="<<b<<endl;
    return 0;

}

通过观察发现,值传递并没有交换a与b的值,因为值传递是不能通过函数外部来改变函数内部的值的,因为他们的地址没有发生根本性的改变。而按地址传递和引用传递交换了a与b的值,因为他们的地址内的数值发生了改变。

9、内联函数inline

函数底层不用做进栈出栈的操作,直接去运行函数内部的操作。适用于量级非常小的函数使用。

注意:不能存在任何形式的循环语句,不能存在过多的条件判断语句,不能对函数进行取地址操作。不一定所以的带inline都可以进行内联操作。

inline int fun()
{
    cout<<"i'm fun..."<<endl;
}
int main()
{
    fun();// 直接用这个语句cout<<"i'm fun..."<<endl去替换当前的语句
    return 0;
}

10、函数重载

函数重载是在C++语言在C语言的基础上新增的功能。函数重载能够在程序中使用多个同名的函数。

函数重载的关键是函数的参数列表(函数特征标)。如果两个函数的参数数目和类型相同,同时参数的排列顺序也相同,则他们的特征标也相同,而与变量名无关。

C++允许定义名称相同的函数,条件是他们的函数特征标不同。如果参数数目、参数类型、排列顺序不同,则特征标也不同。

#include <iostream>
using namespace std;

void fun()
{
    cout<<"0"<<endl;
}
void fun(int a)
{
    cout<<"1"<<endl;
}
void fun(int a,int b)
{
    cout<<"2"<<endl;
}
void fun(double a,int b)
{
    cout<<"3"<<endl;
}
int main()
{
    fun();
    fun(12);
    fun(12.34,90);
    return 0;
}

再次声明:函数重载的条件:C++下允许使用函数名相同

1、在相同的作用域下;

2、参数的个数,类型,排列顺序必须不同;

3、函数的返回值不可以作为函数重载的条件。

11、extern "C"的用法

只要被extern "C"所修饰的代码都会按照C语言的方式去编译

还是拿上一个程序做例子

#include <iostream>
using namespace std;

extern "C" void fun()
{
    cout<<"0"<<endl;
}
extern "C" void fun(int a)//报错
{
    cout<<"1"<<endl;
}
extern "C" void fun(int a,int b)//报错
{
    cout<<"2"<<endl;
}
extern "C" void fun(double a,int b)//报错
{
    cout<<"3"<<endl;
}
int main()
{
    fun();
    fun(12);
    fun(12.34,90);
    return 0;
}

我们会发现加上extern "C"后程序会报错函数名重复的错误,因为C语言中没有函数重载的功能,只有C++中有。

那么它有什么作用呢?当我们进行C语言和C++语言混合编程的时候就派上用场了。

//  math.h
#ifndef _MATH_H_
#define _MATH_H_

int add(int,int);
int sub(int,int);
int multi(int,int);

#endif _MATH_H_
//math.c
#include "math.h"
int add(int a,int b)
{
    return a+b;
}
int sub(int a,int b)
{
    return a-b;
}
int multi(int a,int b)
{
    return a*b;
}
//main.cpp
#include <iostream>
using namespace std;
extern "C" {
   #include "math.h"
}

int main()
{
    int sum=add(23,12);
    cout<<"sum="<<sum<<endl;
    return 0;
}

  • 6
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值