Excel常用函数公式大全
Excel是财务人打交道最多的办公软件,熟练掌握Excel中的函数公式和操作技巧,能有效的提高工作效率,小空今天给大家分享一些常用公式。
壹/IF函数条件判断
IF函数是常用的判断类函数了,能完成非黑即白这类的判断。
举个栗子,考核得分的标准为60分,要判断B列的考核成绩是否合格。
=IF(B4>=9,\”合格\”,\”不合格\”)
IF,相当于普通话的“如果”的意思。
IF(IF(条件表达式,true,false),表达式为真时执行,表达式为假时执行).
贰/VLOOKUP条件查找
VLOOKUP函数是Excel中的一个纵向查找函数:VLOOKUP(查找值,数据表,列序数【匹配条件】)
使用该函数时,需要注意以下几点:
1、第4参数一般用0(或FASLE)以精确匹配方式进行查找。
2、第3参数中的列号,不能理解为工作表中实际的列号,而是指定返回值在查找范围中的第几列。
3、如果查找值与数据区域关键字的数据类型不一致,会返回错误值#N/A。
4、查找值必须位于查询区域中的第一列。
如下图,要查询F4单元格中的员工姓名是什么职务。
叁/根据身份证号码提取出生年月
C4单元格输入公式:=TEXT(MID(B4,7,8),\”0-00-00\”),
向下复制填充。一次性提取所有身份证号码对应的出生日期。
首先用MID函数从B4单元格的第7位开始,提取出表示出生年月的8个字符,结果为:\”19950904\”
再使用TEXT函数将字符串转换为日期样式:\”1995-09-04\”
肆/条件求和
SUMIF用法是:=SUMIF(区域,求和条件,求和的区域)
小空用通俗语解释一下:如果C4:C8区域的分数等于E4单元格的“一班”,就对B4:B8单元格对应的区域求和。
这里知道了条件,那可不可以多种条件求和呢!!!
当然是可以的,就是在公式加多一些条件
SUMIFS用法是:=SUMIFS(求和的区域,条件区域1,指定的求和条件1,条件区域2,指定的求和条件2,……)
伍/从身份证号中提取性别
小空在上面提了怎么用公式提取出生年月日,那提取性别小伙伴们知道怎么设置公式吗?
在目标单元格中输入公式:=IF(MOD(MID(B4,17,1),2),\”女\”,\”男\”)。
1、身份证号码中的第17位代表性别,如果为奇数,则为“男”,如果为偶数,则为“女”。
2、利用Mid函数提取第17位的值,利用Mod函数求余,最后用IF函数判断,如果求余结果为1(暨奇数),则返回“男”,如果其余结果为0(暨偶数),则返回“女”。
这样则可以得出结果了。
陆/提取混合内容中的姓名
比如我们要用一列数据提取出姓名,除了使用高版本的自动填充功能,小空发现还可以使用公式完成:=LEFT(A2,LENB(A2)-LEN(A2))
LENB函数将每个汉字的字符数按2计数的,而LEN函数对所有的字符都按1计数。
所以“LENB(A2)-LEN(A2)”结果就是文本字符串中的汉字个数。LEFT函数从文本的第一个字符开始,返回指定个数的字符,到最终提取出员工姓名哦!
连接合并多个单元格中的内容,可以使用&符号完成。如图,要把合并A列和B列的数据合并在一起就可以使用公式:=A2&B2
像计算员工加班时长时,经常会算加班小时不方便计算。像两个时间的间隔小时数,不足一小时部分舍去,这种在我们计算加班的时长时会用到 =TEXT(B2-B1,”[h]”)
1:如果是只有早上的上班时间和晚上下班打卡时间,我们计算加班时间,以1天8小时工作时间为例,这里采用满一小时才算加班=TEXT(C2-C1,\”[h]\”)-8
2:如果是只有早上的上班时间和晚上下班打卡时间,我们计算加班时间,以1天8小时工作时间为例,这里采用满半小时才算加班=INT((HOUR(D2-D1)*60+MINUTE(D2-D1))/30)/2-8
小空发现有时候有些数据应用很多,一个个填又很麻烦,这时候我们就可以设置一个动态下拉菜单,可以选择数据。如下图所示,要根据A列的数据在C列生成下拉菜单,要求能随着A列数据的增减,下拉菜单中的内容也会自动调整选中要输入内容的单元格区域,数据→下拉菜单→序列
这样就可以直接选择数据了,不需要一个个地重复输入
在工作在经常会应用过透视表,有些小伙伴就不知道怎么设置,以下如图示
透视表的应用很多,还有一些功能选择,大家有空可以探索一下,对于数据的整合都有用。
最后小空给大家整理了一份EX快捷键应用大全,可以保存起来哦~
C语言通用工具库的4个函数
通用工具库包含各种函数,包括随机数生成器、查找和排序函数、转换函数和内存管理函数。在ANSI-C标准中,这些函数的原型都在stdlib.h头文件中。附录B参考资料V列出了该系列的所有函数。现在,我们来进一步讨论其中的几个函数。
1 exit()和atexit()函数
在前面的章节中我们已经在程序示例中用过exit()函数。而且,在main()返回系统时将自动调用exit()函数。ANSI标准还新增了一些不错的功能,其中最重要的是可以指定在执行exit()时调用的特定函数。atexit()通过注册要在退出时调用的函数来提供这一特性,atexit()函数接受一个函数指针作为参数。程序byebye.c演示了它的用法。
Listing 16.16 The byebye.c Program
下面是该程序的一个运行示例:
Enter an integer: 212 212 is even. Thus terminates another magnificent program from SeeSaw Software!
如果在IDE中运行,可能看不到最后两行。下面是另一个运行示例:
在IDE中运行,可能看不到最后4行。接下来,我们讨论atexit()和exit()的参数。
1.1 atexit()函数的用法
这个函数使用函数指针。要使用atexit()函数,只需把退出时要调用的函数地址传递给atexit()即可。函数名作为函数参数时相当于该函数的地址,所以该程序中把signoff或toobad作为参数。然后,atexit()注册函数列表中的函数,当调用exit()时就会执行这些函数。ANSI保证,在这个列表中至少可以放32个函数。最后调用exit()函数时,exit()会执行这些函数(执行顺序与列表中的函数顺序相反,即最后添加的函数最先执行)。 注意,输入失败时,会调用signoff()和toobad()函数;但是输入成功时只会调用signoff()。因为只有输入失败时,才会进入if语句中注册toobad()。另外还要注意,最先调用的是最后一个被注册的函数。 atexit()注册的函数(如signoff()和toobad())应该不带任何参数且返回类型为void。通常,这些函数会执行一些清理任务,例如更新监视程序的文件或重置环境变量。 注意,即使没有显式调用exit(),还是会调用signoff(),因为main()结束时会隐式调用exit()。
1.2 exit()函数的用法
exit()执行完atexit()指定的函数后,会完成一些清理工作:刷新所有输出流、关闭所有打开的流和关闭由标准I/O函数tmpfile()创建的临时文件。然后exit()把控制权返回主机环境,如果可能的话,向主机环境报告终止状态。通常,UNIX程序使用0表示成功终止,用非零值表示终止失败。UNIX返回的代码并不适用于所有的系统,所以ANSI-C为了可移植性的要求,定义了一个名为EXITFAILURE的宏表示终止失败。类似地,ANSIC还定义了EXITSUCCESS表示成功终止。不过,exit()函数也接受0表示成功终止。在ANSI C中,在非递归的main()中使用exit()函数等价于使用关键字return。尽管如此,在main()以外的函数中使用exit()也会终止整个程序。
2 qsort()函数
对较大型的数组而言,“快速排序”方法是最有效的排序算法之一。该算法由C.A.R.Hoare于1962年开发。它把数组不断分成更小的数组,直到变成单元素数组。首先,把数组分成两部分,一部分的值都小于另一部分的值。这个过程一直持续到数组完全排序好为止。 快速排序算法在C实现中的名称是qsort()。qsort()函数排序数组的数据对象,其原型如下:
第1个参数是指针,指向待排序数组的首元素。ANSI C允许把指向任何数据类型的指针强制转换成指向void的指针,因此,qsort()的第1个实际参数可以引用任何类型的数组。 第2个参数是待排序项的数量。函数原型把该值转换为sizet类型。前面提到过,sizet定义在标准头文件中,是sizeof运算符返回的整数类型。 由于qsort()把第1个参数转换为void指针,所以qsort()不知道数组中每个元素的大小。为此,函数原型用第3个参数补偿这一信息,显式指明待排序数组中每个元素的大小。例如,如果排序double类型的数组,那么第3个参数应该是sizeof(double)。 最后,qsort()还需要一个指向函数的指针,这个被指针指向的比较函数用于确定排序的顺序。该函数应接受两个参数:分别指向待比较两项的指针。如果第1项的值大于第2项,比较函数则返回正数;如果两项相同,则返回0;如果第1项的值小于第2项,则返回负数。qsort()根据给定的其他信息计算出两个指针的值,然后把它们传递给比较函数。qsort()原型中的第4个参数确定了比较函数的形式:
这表明qsort()最后一个参数是一个指向函数的指针,该函数返回int类型的值且接受两个指向const void的指针作为参数,这两个指针指向待比较项。 程序qsorter.c和后面的讨论解释了如何定义一个比较函数,以及如何使用qsort()。该程序创建了一个内含随机浮点值的数组,并排序了这个数组。
The qsorter.c Program
下面是该程序的运行示例:
接下来分析两点:qsort()的用法和mycomp()的定义。
2.1 qsort()的用法
qsort()函数排序数组的数据对象。该函数的ANSI原型如下:
第1个参数值指向待排序数组首元素的指针。在该程序中,实际参数是double类型的数组名vals,因此指针指向该数组的首元素。根据该函数的原型,参数vals会被强制转换成指向void的指针。由于ANSI C允许把指向任何数据类型的指针强制转换成指向void的指针,所以qsort()的第1个实际参数可以引用任何类型的数组。 第2个参数是待排序项的数量。在程序清单16.17中是NUM,即数组元素的数量。函数原型把该值转换为sizet类型。 第3个参数是数组中每个元素占用的空间大小,本例中为sizeof(double)。最后一个参数是mycomp,这里函数名即是函数的地址,该函数用于比较元素。
2.2 mycomp()的定义
前面提到过,qsort()的原型中规定了比较函数的形式:
这表明qsort()最后一个参数是一个指向函数的指针,该函数返回int类型的值且接受两个指向const void的指针作为参数。程序中mycomp()使用的就是这个原型:
记住,函数名作为参数时即是指向该函数的指针。因此,mycomp与compar原型相匹配。 qsort()函数把两个待比较元素的地址传递给比较函数。在该程序中,把待比较的两个double类型值的地址赋给p1和p2。注意,qsort()的第1个参数引用整个数组,比较函数中的两个参数引用数组中的两个元素。这里存在一个问题。为了比较指针所指向的值,必须解引用指针。因为值是double类型,所以要把指针解引用为double类型的值。然而,qsort()要求指针指向void。要解决这个问题,必须在比较函数的内部声明两个类型正确的指针,并初始化它们分别指向作为参数传入的值:
简而言之,为了让该方法具有通用性,qsort()和比较函数使用了指向void的指针。因此,必须把数组中每个元素的大小明确告诉qsort(),并且在比较函数的定义中,必须把该函数的指针参数转换为对具体应用而言类型正确的指针。
注意C和C++中的void*C和C++对待指向void的指针有所不同。在这两种语言中,都可以把任何类型的指针赋给void类型的指针。例如,程序清单16.17中,qsort()的函数调用中把double*指针赋给void*指针。但是,C++要求在把void*指针赋给任何类型的指针时必须进行强制类型转换。而C没有这样的要求。例如,程序清单16.17中的mycomp()函数,就使用了这样的强制类型转换:
如何调用qsort()?模仿程序清单16.17中qsort()的函数调用,应该是这样:
这里comp是比较函数的函数名。那么,应如何编写这个函数?假设要先按姓排序,如果同姓再按名排序,可以这样编写该函数:
该函数使用strcmp()函数进行比较。strcmp()的返回值与比较函数的要求相匹配。注意,通过指针访问结构成员时必须使用->运算符。
C++面向对象总结:虚指针与虚函数表,干货又来了
最近在逛B站的时候发现有候捷老师的课程,如获至宝。因此,跟随他的讲解又复习了一遍关于C++的内容,收获也非常的大,对于某些模糊的概念及遗忘的内容又有了更深的认识。
以下内容是关于虚函数表、虚函数指针,而C++中的动态绑定实现和这两个内容是分不开的。
当一个类在实现的时候,如果存在一个或以上的虚函数时,那么这个类便会包含一张虚函数表。而当一个子类继承并重写了基类的虚函数时,它也会有自己的一张虚函数表。
当我们在设计类的时候,如果把某个函数设置成虚函数时,也就表明我们希望子类在继承的时候能够有自己的实现方式;如果我们明确这个类不会被继承,那么就不应该有虚函数的出现。
下面是某个基类A的实现:
从下图中可以看到该类在内存中的存放形式,对于 虚函数的调用是通过查虚函数表来进行的 ,每个虚函数在虚函数表中都存放着自己的一个地址,而如何在 虚函数表中进行查找,则是通过虚指针来调用 ,在内存结构中它一般都会放在类最开始的地方,而对于普通函数则不需要通过查表操作。这张 虚函数表是 什么时候被创建的呢?它是 在编译的时候产生 ,否则这个类的结构信息中也不会插入虚指针的地址信息。
以下例子包含了继承关系:
以上三个类在内存中的排布关系如下图所示:
对于非虚函数,三个类中虽然都有一个叫 func2 的函数,但他们彼此互不关联,因此都是各自独立的,不存在重载一说,在调用的时候也不需要进行查表的操作,直接调用即可。
由于子类B和子类C都是继承于基类A,因此他们都会存在一个虚指针用于指向虚函数表。注意,假如子类B和子类C中不存在虚函数,那么这时他们将共用基类A的一张虚函数表,在B和C中用虚指针指向该虚函数表即可。但是,上面的代码设计时子类B和子类C中都有一个虚函数 vfunc1 ,因此他们就需要各自产生一张虚函数表,并用各自的虚指针指向该表。由于子类B和子类C都对 vfunc1 作了重载,因此他们有三种不同的实现方式,函数地址也不尽相同,在使用的时候需要从各自类的虚函数表中去查找对应的 vfunc1 地址。
对于虚函数 vfunc2 ,两个子类都没有进行重载操作,所以基类A、子类B和子类C将共用一个 vfunc2 ,该虚函数的地址会分别保存在三个类的虚函数表中,但他们的地址是相同的。
从上图可以发现,在类对象的头部存放着一个虚指针,该虚指针指向了各自类所维护的虚函数表,再通过查找虚函数表中的地址来找到对应的虚函数。
对于类中的数据而言,子类中都会包含父类的信息。如上例中的子类C,它自己拥有一个变量 m_data1 ,似乎是和基类中的 m_data1 重名了,但其实他们并不存在联系,从存放的位置便可知晓。
首先来说一说静态绑定: 静态绑定是指在 程序编译 过程中,把函数(方法或者过程)调用与响应调用所需的代码结合的过程(如何理解呢?)
来看一段代码:
可以看到调用的却是派生类的函数。
在没有加 virtual 关键字的时候,通过基类指针指向派生类对象时, 基类指针只能访问派生类的成员变量,但是不能访问派生类的成员函数。 这是因此在系统编译过程中,已经将area()函数和shape类绑定在一起了。
而动态绑定是在加了 virtual 关键字以后,派生类中的成员函数在重写的时候会自动生成自己的虚函数表(单独的一个地址),并通过虚指针指向该地址。
即:shape指针->vptr->Rectangle::area()
通过以上内容,我们可以知道在使用基类指针调用虚函数的时候,它能够根据所指的类对象的不同来正确调用虚函数。而这些能够正常工作,得益于虚指针和虚函数表的引入,使得在程序运行期间能够动态调用函数。
动态绑定有以下三项条件要符合:
使用指针进行调用
指针属于up-cast后的
调用的是虚函数
静态绑定,他们是类对象直接可调用的,而不需要任何查表操作,因此调用的速度也快于虚函数。
写在最后:其实每个人都有自己的选择,学编程,每一种编程语言的存在都有其应用的方向,选择你想从事的方向,去进行合适的选择就对了!对于准备学习编程的小伙伴,如果你想更好的提升你的编程核心能力(内功)不妨从现在开始!
编程学习书籍分享:
编程学习视频分享:
整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)
欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!
对于C/C++感兴趣可以关注小编在后台私信我:【编程交流】一起来学习哦!可以领取一些C/C++的项目学习视频资料哦!已经设置好了关键词自动回复,自动领取就好了!
本文作者及来源:Renderbus瑞云渲染农场https://www.renderbus.com
文章为作者独立观点不代本网立场,未经允许不得转载。