代码编织梦想

函数

认识函数

如何创建函数

  • 常用函数

    • 主函数

      int main()
      {
          return 0;
      }
      
  • 函数基本组成部分

    • 函数返回值类型

    • 函数名

    • 参数列表

    • 函数体

      //自己写的函数,函数的组成
      函数返回值类型 函数名(参数列表)
      {
          函数体;
          return 返回值;
          //返回值: 可以是一个值,可以是一个表达式,因为表达式最终的结果也是一个值,也可以是条件表达式
      }
      
  • 未定义问题

    • 由于函数是自上往下逐步运行的,所以当我们自己定义的函数写在了主函数下面就会出现函数未定义问题
      • 解决办法
        • 在主函数上面声明或者函数实现直接写在主函数前面
  • 一般设计函数遵循单一性原则,也就是一个函数一个功能

函数调用

  • 函数调用:函数名(参数列表);

  • 错误调用

    void printf()
    {
    }
    
  • 返回值类型

    • 有返回值:由后面的return的值的类型决定

    • 无返回值:void

    • C语言只能返回一种类型数据,不存在返回多个值

    • 没有返回值可以存在return

    • 可以通过结构体封装多种数据

    • 函数调用准则:尽量要实参和形参类型保持一致

    • 函数调用的时候所有传参的方式都是赋值的方式,也就是说形参=实参

      float print()
      {
      	return 1.1f;  //1.1f是float类型 需要和函数返回值类型保持一致
      }
      int printA()
      {
      	return 1;    
      }
      
      int printInt()
      {
      	return 12,14,15;    //12,14,15是一个逗号表达式,所以返回15
      }
      //没有返回值
      void printVoid()
      {
      	return ;	//因为在任何一函数中,遇到return 整个函数结束    
      }
      

函数调用的过程

#include <stdio.h>
//求字符串可见长度
int mystrlen(char array[]) 
{
	int count = 0;
	while (array[count] != '\0')
		count++;
	return count;
}
//字符串的连接
void mystrcat(char str1[], char str2[]) 
{
	int i = 0;
	//先走到第一个字符串最后面
	while (str1[i] != '\0')
		i++;
	int j = 0;
	//把第二个字符串赋值到第一个字符串后面
	while (str2[j] != '\0')
		str1[i++] = str2[j++];
	//str1[i++] = str2[j++]
	//i=4 j=0
	//str1[4]=str2[0];
	//str1[5]=str2[1]
}
//字符串的拷贝
//这个问题不需要考虑,str1长度大于str2
void mystrcpy(char str1[], char str2[]) 
{
	int j = 0;
	while (str2[j] != '\0') 
	{
		str1[j] = str2[j];
		j++;
		//str1[0]=str2[0];
		//str1[1]=str2[1];
	}
	str1[j] = '\0';
}
//小写转大写
void myupper(char str[]) 
{
	int i = 0;
	while (str[i] != '\0') 
	{
		if (str[i] >= 'a' && str[i] <= 'z') 
		{
			//a-A=str[i]-result
			//result=str[i]+'A'-'a';
			str[i]+='A' - 'a';
		}
		i++;
	}
}
//大写转小写
void mylower(char str[])
{
	int i = 0;
	while (str[i] != '\0')
	{
		if (str[i] >= 'A' && str[i] <= 'Z')
		{
			//a-A=result-str[i]
			//result=str[i]+'A'-'a';
			str[i] +='a'-'A';
		}
		i++;
	}
}

int main()
{
	char str[] = { "ILoveyou" };  //可见长度不包含\0
	printf("%d\n", mystrlen(str));
	//first大小一定是大于等于 mystrlen(first)+mystrlen(second)
	char first[20] = "str123";
	char second[] = "str2";
	mystrcat(first, second);
	puts(first);
	mystrcpy(first, second);
	puts(first);
	myupper(str);
	puts(str);
	mylower(str);
	puts(str);
	return 0;
}

函数参数

  • 没有参数

    • 没有参数可以什么都不写

    • 没有参数可以写一个void

      //没有参数的
      void  print(void){}
      void printINT(){}
      
      
  • 有参数

    • 形式参数(形参)

      • 在定义一个函数的时候是形式参数(形参)
    • 实际参数(实参)

      • 在调用函数的时候是实际参数(实参)
    • 什么时候需要传参

      • 该函数需要用到调用者所在的函数中的变量的时候,都需要传参
      //有参数的
      void  printAB(int a,int b)   //a和b叫做形式参数
      { 
          //int a=aa ,int b=bb;
          int sum=a+b;
      }
      int main()
      {
          int aa=1;
          int bb=2;
          printAB(aa,bb);  
          return 0;
      }
      

函数参数传参过程

#include <stdio.h>
//所有传参的方式都是参数赋值
int sum(int a, int b) 
{
	return a + b;
}
int Max(int a, int b) 
{
	return a > b ? a : b;
}
void modify(int a)   //int a=1;
{
	a = 1001;
}
int modifyNum() 
{
	return 1001;
}
//特殊传参方式
//数组专有传参方式
//数组充当函数参数的时候通常都需要带上数组的尺寸
//除了字符串数组之外,可以不需要尺寸
//1.一维数组
//通过子函数打印一维数组
void printArray1D(int array1D[], int arrayNum) 
{
	for (int i = 0; i < arrayNum; i++) 
	{
		printf("%d\t", array1D[i]);
	}
	printf("\n");
}
//2.二维数组
//int array[][常量] 并且要和实参的长度一致
void printArray2D(int array[][4], int row, int cols) 
{
	for (int i = 0; i < row; i++) 
	{
		for (int j = 0; j < cols; j++) 
		{
			printf("%d\t", array[i][j]);
		}
		printf("\n");
	}
}

int main() 
{
	int  aa = 1;
	int  bb = 2;
	printf("sum=%d\n", sum(aa, bb));   //实际参数 
	printf("Max=%d\n", Max(aa, bb));   //实参
	int cc = 1;
	modify(cc);		//因为形参是拷贝本,所以不能改变实参的值
	printf("%d\n", cc);					//打印的还是1
	//cc = returnNum();					//通过赋值的修改了cc值
	//printf("%d\n", cc);
	
	int array1D[3] = { 1,2,3 };
	printArray1D(array1D,3);			//传参的时候是数组名
	int num1D[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printArray1D(num1D, 10);
	int array2D[3][4] = { 1,2,3,4,1,2,3,4,1,2,3,4 };
	printArray2D(array2D, 3, 4);	
	return 0;
}

函数返回值

  • 函数返回值是函数调用后唯一产物,也就是函数调用的表达式代表的值

    int main()
    {
        int aa=1;
        int bb=2;
     	int result=returnNum(aa,bb);		//returnNum(aa,bb)代表a+b 表达式的值
        printf("%d\n",returnNum(aa,bb));
        printf("%d\n",result);
        return 0;
    }
    
  • 什么时候需要返回值

    • 在调用者函数中需要用到调用函数处理结果的时候

      int   returnNum(int a,int b)
      {
          return a+b;
      }
      
  • 函数返回值返回的是上面东西由写代码的人决定

函数返回值类型和函数返回值应用

#include <stdio.h>
//声明语法
void print();
//没有返回值的:一般用来做效果类的处理(打印,绘制过程等)
void makeMenu() 
{
	printf("-------------------\n");
	printf("\t0.退出系统\n");
	printf("\t1.录入系统\n");
	printf("\t2.修改\n");
	printf("-------------------\n");
}
int  returnInt() 
{
	int num = 0;
	printf("input a num:");
	scanf_s("%d", &num);
	return  num;
}
//求和
int Sum(int a, int b) 
{
	return a + b;
}
//求大小
int Compare(int a, int b)
{
	return a > b;
}
//当类型不一致的时候的处理
// warning C4244: “return”: 从“float”转换到“int”,可能丢失数据
//以函数返回值类型 做类型转换
//1.11f 转换为int 类型
int returnFloat() 
{
	int temp = 0;		//局部
	return 1.11f;
}
//不要返回值局部变量的地址
int main()
{
	print();   //函数通常描述一个功能,可以重复使用
	print();

	float num = returnFloat();
	return 0;
}

void print() 
{
	printf("ADSF\n");
	printf("dsafcd\n");
	printf("RTGFDFG\n");
	printf("ADSFsdafd\n");
	printf("SFDHerfg\n");
}

函数应用——汉诺塔问题

  • 递归调用

    #include <stdio.h>
    int move(int n, int x, int y, int z) 
    {
        if (n == 1)
            printf("%c--->%c\n", x, z);
        else {
            move(n - 1, x, z, y);
            printf("%c--->%c\n", x, z);
            move(n - 1, y, x, z);
        }
    }
    int main() 
    {
        int h;
        printf("请输入数值:\n");
        scanf_s("%d", &h);
        printf("\n汉诺塔移动如下:%2d级:\n", h);
        move(h, 'a', 'b', 'c');
        return 0;
    }
    
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_54212148/article/details/127149950

c语言基础:函数的定义与调用_怪蛙的博客-爱代码爱编程_函数调用

        在前面内容中我们调用了一个标准C的库函数,叫printf,那么如果我们想自己定义函数应该如何来编写程序呢?定义函数又有什么好处呢?因为我们在教材中提及到的例子主要目的是为了让读者对程序的原理有一定的了解,所以设定的例子程序通常都比较简单,基本上在几行到十几行,多一点的也就三五十行代而已,但是在真正的编程工作中,我们需要完成的代码将非常大,所

C语言基础-函数的概念-爱代码爱编程

c语言基础-函数的概念 一、函数的定义: 将常用的整体实现某个功能的代码块封装起来,用到的时候可以直接调用 函数也是模块化编程的一种体现 二、函数的定义格式: 函数类型 函数名(形参类型 形参名,形参类型 形参名,…………) { 函数的执行语句; return 返回的值; } 函数类型就是函数的返回值类型 三、函数的分类: 1)无形参 无返回

C语言基础知识入门(大全)-爱代码爱编程

一、C语言基础知识入门 C语言一经出现就以其功能丰富、表达能力强、灵活方便、应用面广等特点迅速在全世界普及和推广。C语言不但执行效率高而且可移植性好,可以用来开发应用软件、驱动、操作系统等。C语言也是其它众多高级语言的鼻祖语言,所以说学习C语言是进入编程世界的必修课!   博主已将这些基础知识汇总成了一个PDF版的C语言基础知识大全关注博主的微 信

基于ssm框架的图片分享及评价网站设计与实现 毕业设计-附源码201524_dzbs2000的博客-爱代码爱编程

ssm图片分享及评价网站 摘 要 大数据时代下,数据呈爆炸式地增长。为了迎合信息化时代的潮流和信息化安全的要求,利用互联网服务于其他行业,促进生产,已经是成为一种势不可挡的趋势。在图片分享及评价的要求下,开发一款整体式结构的图片分享及评价系统,将复杂的系统进行拆分,能够实现对需求的变化快速响应、系统稳定性的保障,能保证平台可持续、规模化发展的

基于java演唱会购票系统计算机毕业设计源码+系统+数据库+lw文档+部署_ssh 演唱会门票预约管理系统-爱代码爱编程

基于JAVA演唱会购票系统计算机毕业设计源码+系统+数据库+lw文档+部署 基于JAVA演唱会购票系统计算机毕业设计源码+系统+数据库+lw文档+部署 本源码技术栈: 项目架构:B/S架构 开发语言:Java语言 开发软件:idea eclipse 前端技术:Layui、HTML、CSS、JS、JQuery等技术 后端技术