【C语言程序设计】笔记 day03

P28_函数初体验

1、为什么要自己定义函数?

因为随着程序规模的变大,都免不了会遇到下面这些问题:

  • main 函数变得相当冗杂,程序可读性差
  • 程序复杂度不断提高,编程变成了头脑风暴
  • 代码前后关联度高,修改代码往往牵一发而动全身
  • 变量的命名都成了问题(因为简单的名字都用完了啊,小明,小红,旺财,阿福,隔壁家老王这些名字都用过了,为了不重复命名,只能小明2号,小红3号这样……)
  • 为了在程序中多次实现某功能,不得不重复多次写相同的代码

2、标准库函数

C 语言的标准库中还为我们提供了很多实现各种功能的函数,有处理字符串的,有数学计算的,有输出输入的,有进程管理的,有信号、接口处理的……

看这里,都给你整理好了 -> 传送门

有了这些函数,我们就不用去关注内部的实现细节,只需要将注意力放在程序的实现逻辑上即可。

比如要打印字符串到屏幕上,我们只需要知道调用 printf 函数并给它传递要打印的内容即可,至于它内部是怎么做到的,我们不需要理会。

3、函数的定义

C 语言要求函数必须“先定义,再调用”,定义函数的格式如下:

类型名 函数名(参数列表)
{
函数体
}

  • 类型名就是函数的返回值,如果这个函数不准备返回任何数据,那么需要写上 void(void 就是无类型,表示没有返回值)。
  • 函数名就是函数的名字,一般我们根据函数实现的功能来命名,比如 print_C 就是“打印C”的意思,一目了然。
  • 参数列表指定了参数的类型和名字,如果这个函数没有参数,那么这个位置直接写上小括号即可(())。
  • 函数体就是指定函数的具体实现过程,是函数中最重要的部分。

4、函数的声明

所谓声明(Declaration),就是告诉编译器我要使用这个函数,你现在没有找到它的定义不要紧,请不要报错,稍后我会把定义补上。

有时候,你可能会发现及时不写函数的声明,程序也是可以正常执行的。但如果你把函数的定义写在调用之后,那么编译器可能就会找不着北了:

#include <stdio.h>

int main(void)
{
   
  print_C();
  return 0;
}

void print_C(void)
{
   
  printf(" ###### \n");
  printf("##    ##\n");
  printf("##      \n");
  printf("##      \n");
  printf("##      \n");
  printf("##    ##\n");
  printf(" ###### \n");
}

程序执行后会弹出提醒(一些比较旧的编译器甚至会报错):

image-20220208160919639

这是因为程序的编译时从上到下执行的,所以从原则上来说,函数必须“先定义,再调用”。向上边例子反其道而行就会出问题。但在实际开发中,经常会在函数定义之前使用它们,这个时候就需要提前声明。

声明函数的格式非常简单,只需要去掉函数定义中的函数体再加上分号(;)即可:

#include <stdio.h>

void print_C(void);

int main(void)
{
   
  print_C();
  return 0;
}

void print_C(void)
{
   
  printf(" ###### \n");
  printf("##    ##\n");
  printf("##      \n");
  printf("##      \n");
  printf("##      \n");
  printf("##    ##\n");
  printf(" ###### \n");
}

作为一个良好的编程习惯,建议大家还是无论如何都把函数的声明写上比较合适。

5、函数的参数和返回值

有时候,函数需要接收用户传入的数据,那么就需要使用函数的参数。根据需求,函数的参数数量可以有多个,类型也可以各不相同。

而函数的返回值通常是反馈了函数的计算结果,也可以是函数的执行结果(比如成功或失败)。

请参考以下两个例子:

a. 编写一个函数 sum,由用户输入参数 n,计算 1+2+3+…+(n-1)+n 的结果并返回。

#include <stdio.h>

int sum(int n);

int sum(int n)
{
   
  int result = 0;

  do
  {
   
    result += n;
  } while(n-- > 0);

  return result;
}

int main(void)
{
   
  int n;

  printf("请输入n的值:");
  scanf("%d", &n);

  printf("1+2+3+...+(n-1)+n的结果是:%d\n", sum(n));

  return 0;
}

结果:

image-20220208160958165

b. 编写一个函数 max,接收两个整型参数,并返回它们中的较大的值。

#include <stdio.h>

int max(int, int); // 声明可以只写参数的类型,不写名字

int max(int x, int y)
{
   
  if (x > y)
    return x; // 程序一旦执行return语句,表明函数返回,后边的代码不会继续执行。
  else
    return y;
}

int main(void)
{
   
  int x, y, z;

  printf("请输入两个整数:");
  scanf("%d%d", &x, &y);

  z = max(x, y);

  printf("它们中较大的值是:%d\n", z);

  return 0;
}

结果:

image-20220208161010291

补充:如果函数不需要参数,建议定义时在函数名后边的小括号中写上 void,明确表示该函数无参数。

P29_参数和指针

1、参数和返回值

类型名  函数名(参数列表)
{
   
        函数体
}

函数在定义的时候通过参数列表来指定参数的数量和类型,参数使得函数变得更加的灵活,传入不同的参数可以让函数实现更为丰富的功能。如果你的函数确实不需要参数,建议使用 void 进行强调。

函数的类型名事实上就是指定函数的返回值。你一个函数,实现了一个功能,经常是要反馈结果的,比如我传给你两个数字 1 和 2,你将它们进行复杂的计算之后把结果 3 返回给我。当然,在现实开发中也并不是所有的函数都有计算结果可以返回,比如你调用一个函数用于在窗口中绘制一个矩形,那么它就没有什么所谓的计算结果需要返回了,所以通常这些函数会通过返回值来说明该函数是否调用成功。最后,如果你的函数确实不需要返回值,那么就用 void 表示不返回。

2、形参和实参

形参就是形式参数,函数定义的时候写的参数就叫形参,因为那时候它只是作为一个占位符而已。而实参就是你在真正调用这个函数的时候,传进去的数值。

形参和实参的功能说白了就是用作数据传送。当发生函数调用时,实参的值会传送给形参,并且这种传输具有单向性(也就是不能把形参的值回传给实参)。另外,形参变量只有在函数被调用时才会分配内存,调用结束后,立刻释放内存,所以形参变量只有在函数内部有效,不能在函数外部使用。

3、传值和传址

指针也是一个变量,所以它可以通过参数传递给函数。

无论是传值还是传址,都只是将实参的值拷贝给形参。

case01 传值

传值

#include <stdio.h>

void swap(int x, int y);

void swap(int x, int y)
{
   
	int temp;

	printf("In swap, 互换前:x = %d, y = %d\n", x, y)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值