首页 > 其他分享 >C语言学习笔记(三)函数和递归

C语言学习笔记(三)函数和递归

时间:2023-07-22 14:12:38浏览次数:38  
标签:arr return 函数 递归 int 笔记 C语言 include 自定义

函数和递归

库函数

strcpy()

​ 使用之前要先包含<string.h>

​ 拷贝时会将\0一起拷贝(注意:/0是字符串结束的标志,但计算长度时不计入)

memset() 内存设置

​ 使用之前要先包含<string.h>

#include<stdio.h>
#include<string.h>
int main()
{
	char arr[]="hello world";
	memset(arr,'*',5);//arr为要修改的地址 中间的内容不能为字符串 5表示修改内存中的5位
	printf("%s\n",arr);
	return 0;
}

自定义函数

函数的基本组成与使用

image-20230714165944914
//定义函数,要写在主函数外面

返回值类型 函数名(函数类型 参数,)

{
	函数体;
}
  1. 返回值类型写为void,代表这个函数没有返回值

  2. 实参可以是常量、变量、表达式、函数等,反正必须要有确切的值

形式参数当函数调用完成后就会销毁,调用函数时才实例化,为形式参数分配内存空间

int* p=&a; //&a代表地址,把该地址赋给指针变量p
*p=20;//*p代表该地址所存储的内容,此处即将a的内容改为20
  1. 利用自定义函数来改变主函数中变量的值(传地址)
//自定义函数交换变量的值
#include<stdio.h>
#include<string.h>

void SWAP(int* pa,int* pb)//pa,pb是形参
{
    int tmp=0;
    tmp=*pa;
    *pa=*pb;
    *pb=tmp;
}
int main()
{
	int a=3,b=5;
    printf("a=%d,b=%d\n",a,b);
    SWAP(&a,&b); //&a,&b是实参
    printf("a=%d,b=%d",a,b);
	return 0;
}
  1. 形参是实参的一份临时拷贝,形参改变不会影响实参

函数的调用

传值调用

​ 形参和实参分别占有不同内存块,对形参的修改不会影响实参

传址调用

​ 传址调用是把自定义函数外部创建变量的内存地址传递给自定义函数的参数的一种函数调用方式

​ 这种传参方式可以让自定义函数和自定义函数函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量

​ 即当我想要利用自定义函数改变主函数中传入自定义函数的变量的值时,使用传址调用

数组传参

  1. 数组在函数间传递时,传递的不是数组本身,而是数组的首元素的地址。

​ 例:

#include<stdio.h>
#include<string.h>

int a_Search(int arr[],int l,int b)//arr[]本质是一个指针
{
    int left=0;
    int right=l-1;
   //错误写法:int l=sizeof(arr)/sizeof[0]; 
   //此处无法用这种方法计算数组长度,因为此时arr代表的是首元素的地址,而不是整个数组
    int x;

    while(left<=right)
    {
        x=(left+right)/2;
        if(arr[x]<b)
        {
            left=x+1;
        }
        else if(arr[x]>b)
        {
            right=x-1;
        }
        else if(arr[x]==b)
        {return x;}
    }

    while(left>right)
    {
        return -1; //找不到,返回-1
    }
}

int main()
{
    int arr[]={1,2,3,4,5,6,7,8,9,10};//整型数组(不是char类型)
    int k = 7;
    int l=sizeof(arr)/sizeof(arr[0]);
    //错误写法:int ret = a_Search(arr,k);   此处传递的实际上是数组首元素的地址
    int ret=a_Search(arr,l,k);  //正确写法:在主函数里计算出数组长度,一并传递给自定义函数
    if(ret==-1)
    {
        printf("can't find!");
    }
    else
    printf("the number is at %d",ret);
    return 0;
}

嵌套调用

例:

​ 主函数中调用自定义函数A();

​ A函数的定义里调用了自定义函数B();

​ 再定义函数B();

链式访问

把一个函数的返回值作为另一个函数的参数;

函数的声明和定义

函数声明

  1. 告诉编译器:函数叫什么、参数是什么、返回类型是什么。但函数是否具体存在无关紧要。

  2. 先声明后使用

  3. 函数的声明一般放在头文件(.h)中,引用自己写的头文件用双引号 include "add,h"

​ 例:

int Add(int x,int y);//声明有一个Add()函数

函数定义

例:

int Add(int x,int y)
{
	int z=x+y;
	return z;
}

如果函数的定义在函数调用的前面,则不需要函数声明

函数的递归

一个过程或函数在其定义或说明的过程中直接或间接调用自身的一种方法

递归的主要思考方式:把大事化小

递归的两个必要条件

  • 存在限制条件,当满足限制条件时,递归不再继续。
  • 每次递归调用后原来越接近这个限制条件

例题

不创建临时变量,求字符串的长度

#include<stdio.h>

int my_strlen(char* arr)
{
    if(*arr != '\0')
    {
        return 1+my_strlen(arr+1);
    }
    else
        return 0;
}   
int main()
{
    char arr[]="abcdefg";
    int len=my_strlen(arr);//传递的是arr的首个元素的地址
    printf("Len=%d",len);
    return 0;
}

有时候递归会导致运算结果很慢。可以考虑使用循环或者迭代。

其他

  1. 判断是否是闰年:年份能被400整除则是闰年

  2. ++的优先级比*高,即先执行++

    int* p;
    *p++;//无法成功实现对p+1
    (*p)++;//成功
    
  3. printf()函数的返回值打印的字符的个数

标签:arr,return,函数,递归,int,笔记,C语言,include,自定义
From: https://www.cnblogs.com/arongsec/p/17573294.html

相关文章

  • C语言学习笔记(四)数组
    数组一维数组的创建和初始化//创建类型数组名[元素个数];intarr[10];chararr2[5];//初始化intarr[10]={1,2,3};//不完全初始化chararr[5]={'a','b'};chararr3[5]="ab";//每一位为:a,b,末尾有\0chararr6[]="abcdef";//没有确定长度则必须进行初始化,根据初始......
  • C语言编程必备技能!小写转大写
    在C语言中,要区分字母的大小写,可以利用ASCII码中大写字母和小写字母之间的转换关系,差值为32,通过这个差值可以将小写字母转换为大写字母。下面编写程序实现该功能:从键盘输入一个小写字母,按回车键后,程序将该小写字母转换为大写字母,并输出其ASCII值。 程序的算法思想如下:......
  • re: 从零开始的学PPT笔记
    深夜模式:账户\(\rightarrow\)office主题神奇操作:.ppt后缀改成.rar居然可以解压/jy默认设置:账户\(\rightarrow\)保存\(\rightarrow\)字体嵌入;账户\(\rightarrow\)高级设置\(\rightarrow\)不压缩图片默认字体:设计\(\rightarrow\)变体右下角\(\rightarrow\)字......
  • 算法学习笔记(26): 计算几何
    计算几何向量高一知识,略讲。向量外积若\(\vecx=(x_1,y_1),\vecy=(x_2,y_2)\),则有\(\vecx\times\vecy=x_1y_2-y_1x_2\)。或者表示为\(|\vecx||\vecy|\sin\theta\),其中\(\theta\)表示向量间的夹角。几何意义:两个向量构成的平行四边形的面积(可以......
  • JavaScript学习笔记
    之所以学习JS是想更清楚的了解这门语言,记得上学那会就感觉j真难学,工作了几年了一直从事后端,但偶尔也会用前端开发,这时候就会手忙脚乱, 好多东西都是默默糊糊,还有就是,我想知道这门语言真的很难学吗?抱着好奇的心态开始了一个月的学习历程,下面整理一下一个月的学习笔记.跟着......
  • 线性基学习笔记
    线性基的定义在一个高维空间中一组极大的线性无关的向量组成为一组线性基,更严谨的定义参考线性代数相关内容。但是在OI中我们常用的是异或线性基,它维护了给定若干个数能够通过异或计算出的所有的数,具体来说可以实现以下几个功能:求min/max异或和求k大异或和求异或和数......
  • Django学习笔记:第二章django的安装和创建应用
    1.安装Django终端运行pipinstalldjango查看django是否安装成功python-mdjango--version1.1安装虚拟环境在控制台运行pipinstallvirtualenv1.1.2创建虚拟环境在特定文件夹内打开终端运行virtualenv-pD:\program_condition\python\python.exeenv_djvir......
  • 概率期望学习笔记总结
    一.OSU!题目背景原《产品排序》参见P2577题目描述osu是一款群众喜闻乐见的休闲软件。我们可以把osu的规则简化与改编成以下的样子:一共有\(n\)次操作,每次操作只有成功与失败之分,成功对应\(1\),失败对应\(0\),\(n\)次操作对应为\(1\)个长度为\(n\)的01串。在......
  • 「学习笔记」AC 自动机
    AC自动机是 以Trie的结构为基础,结合 KMP的思想 建立的自动机,用于解决多模式匹配等任务。Trie的构建这里需要仔细解释一下Trie的结点的含义,Trie中的结点表示的是某个模式串的前缀。我们在后文也将其称作状态。一个结点表示一个状态,Trie的边就是状态的转移。形式化地......
  • 树上启发式合并学习笔记
    树上启发式合并\((dsu\on\tree)\)适用条件:可以在一个子树内统计的问题,并且不带修改。暴力复杂度一般为\(O(n^2)\)。例题:CF600ELomsatgelral解法考虑一个问题,给你一棵树,每个节点有一个颜色,如果一种颜色在以\(x\)为根的子树内出现次数最多,则称\(col_i\)占主要色。......