C/C++函数从零到底层原理

简介: C/C++函数从零到底层原理



1.函数定义模板:返回类型  函数名 (参数1,参数2,参数3······){函数体内容及参数}

void sort(int *array){}
void(返回类型)sort(函数名称)(int *array)(函数参数){函数体}

2.函数声明

1)为什么要有申明?

因为计算机是从主函数从上到下执行的,如果函数定义在使用之前,自然不需要定义,因为计算机已经识别了函数,但如果没有,计算机就会报”无法解析的外部命令“的错误,但是在工程和编写大的程序时这样的方法就不现实了,这样会严重影响函数的可读性,函数的申明就是为了让计算机提前识别函数。

2)函数声明的格式(以前面函数为例,放在使用之前)
void sort(int* array);
3.函数栈帧的建立与销毁,接下来先理解示范代码
#include<stdio.h>
int Add(int a, int b) {
  return a + b;
}
int main() {
  int a, b;
  scanf("%d%d", &a, &b);
  int c = Add(a, b);
  return 0;
}

1)函数名其实是地址,函数只有一份,在计算机运行到这里的时候它就会通过地址找到函数,但是在它进入函数是还要有几个操作,首先保存当前运行的地址,然后将参数进行压栈拷贝一份(仅限传值),然后通过在进入函数,在函数执行完毕后就会进行销毁出栈,接下来看我下面的图理解

2)拓展

1)函数指针为何物?

大家都知道有整形指针,浮点型指针,那么既然函数名是一个地址,那我们能不能用指针来接收它的地址呢,答案是YES。既然我们知道函数是能用指针来接收的,那我们应该如何来接收它呢?首先指针的类型是与函数返回值相同的,其次要有 * ,然后应该是指针的命名,为了保证 * 和指针名字结合,需要用括号合并二者,后面则是函数的参数类型,不一定要有参数的名称,但需要点明参数的类型。接下来我们展示一下如果写出函数相对应的指针

1)
int Add(int a,int b);
//一一对应
int (*ptr)(int ,int )=Add;
2)
int *ButNode(struct Node* List, int n);
//一一对应
int *(*ptr)(struct Node*,int)=BuyNode;
2)主函数的讨论

主函数虽然是多了一个主字,但是它本质也是函数,本质它是第一个执行的函数,主函数是通过编译系统已经存在的函数引用的,由于其中涉及到底层的实现原理,考虑难度较大,我这里推荐使用VS2019去观察主函数之前代码的运行,观察步骤较为复杂,这里不做过多描述,请查阅网上资料自行探索。接下来你可以去了解一下函数的有意思用法,如函数递归,有一种化繁为简的美学。

如果大家有收获的话不如三连(关注加点赞加收藏)see you

相关文章
|
4月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
92 0
|
7月前
|
安全 C++
【c++】继承(继承的定义格式、赋值兼容转换、多继承、派生类默认成员函数规则、继承与友元、继承与静态成员)
本文深入探讨了C++中的继承机制,作为面向对象编程(OOP)的核心特性之一。继承通过允许派生类扩展基类的属性和方法,极大促进了代码复用,增强了代码的可维护性和可扩展性。文章详细介绍了继承的基本概念、定义格式、继承方式(public、protected、private)、赋值兼容转换、作用域问题、默认成员函数规则、继承与友元、静态成员、多继承及菱形继承问题,并对比了继承与组合的优缺点。最后总结指出,虽然继承提高了代码灵活性和复用率,但也带来了耦合度高的问题,建议在“has-a”和“is-a”关系同时存在时优先使用组合。
353 6
|
8月前
|
安全 C语言 C++
彻底摘明白 C++ 的动态内存分配原理
大家好,我是V哥。C++的动态内存分配允许程序在运行时请求和释放内存,主要通过`new`/`delete`(用于对象)及`malloc`/`calloc`/`realloc`/`free`(继承自C语言)实现。`new`分配并初始化对象内存,`delete`释放并调用析构函数;而`malloc`等函数仅处理裸内存,不涉及构造与析构。掌握这些可有效管理内存,避免泄漏和悬空指针问题。智能指针如`std::unique_ptr`和`std::shared_ptr`能自动管理内存,确保异常安全。关注威哥爱编程,了解更多全栈开发技巧。 先赞再看后评论,腰缠万贯财进门。
342 0
|
12月前
|
程序员 C++ 容器
在 C++中,realloc 函数返回 NULL 时,需要手动释放原来的内存吗?
在 C++ 中,当 realloc 函数返回 NULL 时,表示内存重新分配失败,但原内存块仍然有效,因此需要手动释放原来的内存,以避免内存泄漏。
|
12月前
|
存储 前端开发 C++
C++ 多线程之带返回值的线程处理函数
这篇文章介绍了在C++中使用`async`函数、`packaged_task`和`promise`三种方法来创建带返回值的线程处理函数。
443 6
|
12月前
|
编译器 C语言 C++
C++入门3——类与对象2-2(类的6个默认成员函数)
C++入门3——类与对象2-2(类的6个默认成员函数)
107 3
|
12月前
|
C++
C++ 多线程之线程管理函数
这篇文章介绍了C++中多线程编程的几个关键函数,包括获取线程ID的`get_id()`,延时函数`sleep_for()`,线程让步函数`yield()`,以及阻塞线程直到指定时间的`sleep_until()`。
190 0
C++ 多线程之线程管理函数
|
12月前
|
C++
C++番外篇——虚拟继承解决数据冗余和二义性的原理
C++番外篇——虚拟继承解决数据冗余和二义性的原理
123 1
|
12月前
|
编译器 C语言 C++
详解C/C++动态内存函数(malloc、free、calloc、realloc)
详解C/C++动态内存函数(malloc、free、calloc、realloc)
2047 1
|
12月前
|
存储 编译器 C++
C++入门3——类与对象2-1(类的6个默认成员函数)
C++入门3——类与对象2-1(类的6个默认成员函数)
139 1