C语言X天学习计划——数组、函数

写在前面:本文主要是结合郝斌老师的教程所写。如有不恰当的地方,欢迎大家指点批评。

帅帅又来了

在这里插入图片描述

数组

一位数组

  1. 为n个变量连续分配存储空间;
  2. 数据类型必须一致;
  3. 所有变量所占字节必须相等;

例一:第一个数组程序

/*
	2021年1月10日
	第一个数组程序
*/

# include <stdio.h>

int main(void)
{
	int i;
	int a[5] = {1, 2, 3, 4, 5};

	for (i=0; i<5; i++)
		printf("%d\n", a[i]);


	return 0;
}


/*
--------------------------------
在VC++6.0中运行结果为:
1
2
3
4
5
--------------------------------
*/

数组初始化

  1. 完全初始化:
    int a[5] = {1, 2, 3, 4, 5};
  2. 不完全初始化,未被初始化的自动为零
    int a[5] = {1, 2, 3};
  3. 不初始化,所有元素都是垃圾值:
    int a[5]
  4. 清零:
    int a[5] = {0};

错误写法

1.定义数组的同时对整体赋值,其他情况错误

int a[5];
a[5] = {1,2,3,4,5}; 	// 错误


int a[5] = {1, 2, 3, 4, 5};		// 正确

2.超出数组范围

int a[5] = {1, 2, 3, 4, 5};
a[5] = 100; 	// 没有a[5]

3.数组A、B值复制

int a[5] = {1, 2, 3, 4, 5};
int b[5];
// b = a; 错误
-------------------------------------------
int a[5] = {1, 2, 3, 4, 5};
int b[5];
for (i=0; i<5; i++)
	b[i] = a[i];	// 正确

例二:数组数据的倒置

/*
	2021年1月11日
	数组数据的倒置
*/

# include <stdio.h>

int main(void)
{
	int a[5] = {1,2,3,4,5};
	int i;
	int b[5];

	for (i=0; i<5; i++)
	{
		b[i] = a[4-i];
		printf("%d\n", b[i]);
	}

	return 0;
}

/*
---------------------------------
在VC++6.0中运行结果为:
5
4
3
2
1
---------------------------------
*/

数组作为参数传递

/*
	2021年1月20日13:47:34
	求数组最大值
	目的:数组与函数相结合使用
*/

# include <stdio.h>
# define Max 5

void findmax(int values[Max])
{
	int i;
	int max = values[0];

	for (i=1; i<Max; i++)
	{
		if (max < values[i])
			max = values[i];
	}

	printf("该数组最大值为:%d\n", max);
}

int main(void)
{
	int nums[Max] = {2, 5, 85, 6, 91};
	findmax(nums);

	return 0;
}

/*
-------------------------------------------
在VC++6.0中运行的结果为:
该数组最大值为:91
-------------------------------------------
*/

二维数组

int a[4][5];		// 数组顺序:a[0][0],a[0][1]……

初始化

1.标准初始化

int a[3][4] = {
				{1, 2, 3, 4},	// ,
				{4, 5, 6, 7},
				{8, 9, 10, 11}

};	// ;

2.二维数组的一个输出

/*
	2021年1月11日
	二维数组的一个输出
*/

# include <stdio.h>

int main(void)
{
	int a[3][4] = {
					{1, 2, 3, 4},
					{4, 5, 6, 7},
					{8, 9, 10, 11}

	};

	printf("%d\n", a[2][3]);	// 最大位置的元素

	return 0;
}

/*
----------------------------------------
在VC++6.0中运行结果为:
11
----------------------------------------
*/

3.二维数组全部输出

/*
	2021年1月11日
	二维数组内容全部输出:借助for循环
*/
# include <stdio.h>

int main(void)
{
	int i,j;
	int a[3][4] = {
		{1, 2, 3, 4},
		{5, 6, 8, 9},
		{7, 10,11,12}
	};
	

	for (i=0; i<3; i++)
	{
		for (j=0; j<4; j++)
			printf("%d  ", a[i][j]); // printf("%-3d", a[i][j]); 左对齐
		printf("\n");
	}

	
	return 0;
}

/*
-------------------------------
在VC++6.0中运行结果为:
1  2  3  4
5  6  8  9
7  10  11  12
--------------------------------
*/

函数(面向过程的理解)

1.why

  1. 避免程序化操作;
  2. 有利于程序模块化;

2.what

  1. 能够完成特定功能的独立的代码单元

3.how

  1. 函数的返回值 函数的名字(函数的形参列表)
    {
    函数的执行体
    }
  2. return
  3. 函数的返回值的类型
/*
	2021年1月11日
	函数返回值类型
*/

# include <stdio.h>

int f()		//  ---->int 决定返回值类型
{
	return 10.2;	// 因为函数的返回值类型是int,所以最终返回值是10 不是10.2
}

int main(void)
{
	
	int i = 99;
	float x = 6.0;

	x = f();
	printf("%lf\n", x);

	return 0;
}

/*
--------------------------------------------------------------------------------
在VC++6.0中运行结果为:
10.000000
--------------------------------------------------------------------------------
*/

函数调用

/*
	2021年1月22日10:56:05
	函数的简单调用
	《C语言从入门到精通》
*/
# include <stdio.h>

void printstar()
{
	printf("************************\n");
}

int sum(int a, int b)
{
	return a+b;
}

int main(void)
{
	int x, y, z;
	x = 3;
	y = 2;

	printstar();		// 调用printstar()函数
	z = sum(3, 2);		// 调用sum() 函数
	printf("%d + %d = %d\n", x, y, z);
	printstar();

	return 0;
}

/*
------------------------------------------
在VC++6.0中运行结果为:
************************
3 + 2 = 5
************************
------------------------------------------
*/

break 和 return 的用法

例一:break 的用法:终止循环和switch

/*
	2021年1月11日
	break 的用法
*/

# include <stdio.h>

void f(void)	// 无返回值时需要写成void(空类型)
{
	int i;

	for (i=0; i<5; i++)
	{
		printf("大家好!\n");
		break; 	// 仅仅终止循环
	}
	printf("同志们好!\n");
}

int main(void)
{
	f();

	return 0;
}

/*
-----------------------------
在VC++6.0中运行结果为:
	大家好!
	同志们好!
-----------------------------
*/

例二:return 的用法:终止被调函数,向主调函数返回表达式的值

/*
	2021年1月11日
	return 的用法
*/

# include <stdio.h>

void f(void)	// 无返回值时需要写成void(空类型)
{
	int i;

	for (i=0; i<5; i++)
	{
		printf("大家好!\n");
		return;		// return 终止整个函数
	}
	printf("同志们好!\n");
}

int main(void)
{
	f();

	return 0;
}

/*
-----------------------------
在VC++6.0中运行结果为:
	大家好!
-----------------------------
*/

例三:void int 的return
(表达式为空,则只终止函数,不向被调函数返回任何值)

void f()
{
	return;		//  void 时 return 后不用跟数字
}

int max()
{
	return 10;	// int 时 return 返回数字 否则报错
}

函数的分类

  1. 有参函数 和 无参函数
  2. 有返回值 和 无返回值
  3. 库函数 和 自定义函数
  4. 普通函数 和 主函数(一个程序有且只能有一个主函数,主函数调用普通函数,普通函数之间可以相互调用,主函数时程序的入口)
  5. 值传递函数 和 地址传递函数

判断素数

/*
	2021年1月11日
	判断数字是否为素数 ---仅用主函数实现(1)
*/

# include <stdio.h>

int main(void)
{
	int val;
	int i;

	scanf("%d", &val);
	for (i=2; i<val; i++)
	{
		if (val%i == 0)
			break;
	}
	if (i == val)
		printf("Yes!\n");
	else
		printf("No!\n");

	return 0;
}

/*
---------------------------------
在VC++6.0中运行结果为:
5
Yes!

62
No!
---------------------------------
*/


/*
	2021年1月11日
	判断数字是否为素数-----用函数操作(2)
*/

# include <stdio.h>

bool IsPrime(int val)		// 形参个数由功能确定
{
	int i;
	
	for (i=2; i<val; i++)
	{
		if (val%i == 0)
			break;
	}
	if (i == val)
		return true;
	else 
		return false;
}

int main(void)
{
	int m;

	scanf("%d", &m);
	if (IsPrime(m))
		printf("Yes!\n");
	else
		printf("No!\n");
		
	return 0;
}

/*
---------------------------------
在VC++6.0中运行结果为:
5
Yes!

62
No!
---------------------------------
*/


函数声明

  1. 定义函数必须放在被调函数的前面,否则在开始位置必须有函数声明
# include <stdio.h>

void f(void);	// 函数声明 ";必须有"

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

void f(void)	// 定义函数
{
	printf("hh!\n");
}

形参和实参

形参和实参的关系

  • 形参只是一个形式,在调用前并不分配内存空间。函数调用时,系统为形参分配内存单元,然后将主调函数中的实参传递给被调函数的形参。被调函数执行完毕后,通过return 语句返回结果,系统将形参的内存单元释放
  • 实参形参只能单向传递即(实参---->形参)
  • 实参形参可以重名,因为形参实参分居在不同的内存单元,两者没有影响。
/*
	2021年1月12日
	形参实参关系:一一对应
*/

# include <stdio.h>

void f(int i, float x)	// int i, float x 形参
{
	printf("i = %d x = %f\n", i, x);
}

int main(void)
{
	f(5, 6.0);	// 5, 6.0 实参

	return 0;
}

/*
-----------------------------------------
在VC++6.0中运行结果为:
i = 5 x = 6.000000
-----------------------------------------
*/
/*
	2021年1月22日12:10:27
	使用函数交换两个数的值
	《C语言从入门到精通》
	目的:形参实参两者的相互影响、参数传递
*/
# include <stdio.h>

void swap(int a, int b)		// a , b 形参是局部变量只能在被调函数内部执行
{
	int temp;

	temp = a;
	a = b;
	b = temp;

	printf("a = %d, b = %d\n", a, b);
}

int main(void)
{
	int x, y;

	printf("请输入两个数x,y(中间用空格分隔):\n");
	scanf("%d %d", &x, &y);
	printf("交换前x = %d, y = %d\n", x, y);
	printf("调用函数中:\n");
	swap(x, y);									// 形参是实参的copy 形参不会影响实参的变化 
	printf("交换后x = %d, y = %d\n", x, y);		// 形参的值并不能反过来传递给实参 所以实参仍然不变

	return 0;
}

/*
-----------------------------------------------------
在VC++6.0中运行结果为:
请输入两个数x,y(中间用空格分隔):
24 6
交换前x = 24, y = 6
调用函数中:
a = 6, b = 24
交换后x = 24, y = 6
-----------------------------------------------------
*/

函数的嵌套

/*
	2021年1月22日14:24:43
	函数的嵌套
	《C语言从入门到精通》
*/
# include <stdio.h>

fun2(int x, int y)		// 省略不写 默认int 类型
{
	int z_1;

	z_1 = 2 * x - y;

	return z_1;
}

fun1(int x, int y)
{
	int z_2;

	z_2 = fun2(x, x+y);

	return z_2;
}

main()
{
	int a, b, c;

	printf("请输入两个整数:\n");
	scanf("%d %d", &a, &b);
	printf("a = %d b = %d\n", a, b);
	c = fun1(a, b);

	printf("c = %d\n", c);

	return 0;

}
/*
--------------------------------------
在VC++6.0中运行结果为:
请输入两个整数:
6 9
a = 6 b = 9
c = -3

试数:
main函数
a = 6  b =  9                    //	实参

调用fun1后
x = 6 y = 9
fun2(6, 15)

调用fun2后
x = 6 y = 15
z_1 = 2 * 6 - 15 = -3
return z_1;

返回fun1
z_2 = z_1 = -3;
return z_2;

main函数
c = -3
--------------------------------------
*/

实际中的函数

  1. 简化代码
  2. 一个函数的功能应该尽量单一
/*
判断是否为素数(2)
*/
# include <stdio.h>

bool IsPrime(int j)
{
	int i;
	for (i=2; i<j; i++)
	{
		if(0 == j % i)
			break;
	}
	
	if (j == i)
		return true;
	else 
		return false;

}

int main(void)
{
	int val;

	printf("请输入一个数字:");
	scanf("%d", &val);
	if (IsPrime(val))
		printf("Yes!\n");
	else
		printf("No!\n");

	return 0;
}

常用的系统函数

  • 机械工业出版的《turboc2.0实用大全》
  1. double sqrt (double x);(求平方根)
  2. int abs (int x); (求绝对值)
  3. double fabs (double x); (求绝对值)

递归

  • 程序一:递归求阶乘 (n! = ?)
/*
	2021年1月22日14:45:34
	递归求阶乘 (n! = ?)
	《C语言从入门到精通》
*/

# include <stdio.h>

long fac(int n)
{
	long m;
	if (n == 1)
		m = 1;
	else
		m = fac(n - 1) * n;		// 函数自我调用

	return m;
}

main()
{
	int n;

	printf("input a value n:");
	scanf("%d", &n);
	printf("%d! = %d\n", n, fac(n));
	
	return 0;
}

/*
-------------------------------------
在VC++6.0中运行的结果为:
input a value n:5
5! = 120
-------------------------------------
*/
  • 程序二:递归求斐波那契数列
/*
	2021年1月22日15:28:18
	递归求斐波那契数列
	《C语言从入门到精通》
*/
# include <stdio.h>

long fibonacci(int n)
{
	if (n == 1 || n == 2)
		return 1;
	else 
		return (fibonacci(n -1) + fibonacci(n - 2));
}

main()
{
	int n, i;
	long y;

	printf("input n:");
	scanf("%d", &n);

	for(i=1; i<=n; i++)
	{
		y = fibonacci(i);
		printf("%d\t", y);
		
		if (i % 10 == 0)		// 换行
		{
			printf("\n");
		}
	}

	printf("\n");
}

/*
---------------------------------------------------------------------------
在VC++6.0中运行结果为:
input n:19
1       1       2       3       5       8       13      21      34      55
89      144     233     377     610     987     1597    2584    4181
---------------------------------------------------------------------------
*/

  • 程序三:带参数的main函数
/*
	2021年1月22日16:00:41
	带参数的main函数
	目的:调试
	《C语言从入门到精通》
*/
# include <stdio.h>

int main(int argc, char *argv[])
{
	int count;

	printf("The command line has %d arguments:\n", argc-1);

	for (count=1; count<argc; count++)
		printf("%d:%s\n",count,argv[count]);
}

/*
--------------------------------------------------------------------------------
在VC++6.0中运行结果为:
The command line has 3 arguments:
1:I
2:am
3:happy!

The command line has 2 arguments:
1:100
2:255
--------------------------------------------------------------------------------
注意:

1.主函数中带有参数需要调试步骤
project --> Settings --> Debug --> program arguments(输入参数)--> OK

2.在命令行中输入的都将作为字符串形式存储于内存中 任何形式都必须以%s格式输出

--------------------------------------------------------------------------------
*/

变量的作用域和存储方式

  1. 按作用域分:
  • 全局变量:函数外部定义的变量
  • 局部变量:函数内部的变量或者形参
int k = 0;	// 全局变量

void f(int i)	// int i 局部变量
{
	int j = 30;		// 局部变量
}
  • 局部变量和全局变量同名时,全局变量会被局部变量屏蔽
  1. 按存储方式分:
  • 静态变量
  • 自动变量
  • 寄存器变量

你知道我缺点什么

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

想前

看客 多少意思意思

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值