Day 9



将数组每行的平均值打印出来:

#include <stdio.h>
int main(void)
{
	int a[][5] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25};
	int row = sizeof(a) / sizeof(a[0]);
  //printf("%d\n ", row);
	int col = sizeof(a[0]) / sizeof(a[0][0]);
  //printf("%d\n ", col);
	int i,j,sum = 0;
	for(i = 0; i < row; ++i)   //错误的两句 for(i = 0; i < row; ++row) 
	{
		for(j = 0; j < col; ++j) //for(j = 0; j < col; ++col)
		{
			sum += a[i][j];
	//		printf("%d\n ", sum);
		}
		sum /= col;
		printf("%d\n ", sum);
	    sum = 0;
	//	break;
	} 
	return 0;
}

for 循环里面应该写为 ++i, ++j,
循环的三个要素:(1)循环变量的初始化
(2)循环执行的条件
(3)有使循环趋于结束的语句
昨天的问题在于缺少了第三点,使循环趋于结束的语句。

int i = 3; j = 3;
//上面的写法是错误的当[][]里面是变量时则不能初始化。

#define N 3
int a[N][N] = {1,2,3,4,5,6,7,8,9};
//此种写法是正确的,因为N是 define的一个常量。

//Linux 环境下,用gcc编译时可以加参数 -Wall(Warning all)来显示所有警告。
3.函数:
函数的形式: 类型标识符 函数名(形参)
{
声明部分;
语句部分;

			}

//不能在函数的内部再定义函数。

//声明 :可以多次。 定义:从无到有,只有一次。

//当函数没有返回值时,默认为int类型,但比较好的方式是,写函数时一定要加类型标识符,
不管是有返回类型( int, char, double ,等)还是无返回类型( void )都要加,这样可以避免歧义。

//函数的传参有两种: (1)值传递: 只传实参的值,形参只是实参的复制品,不可以修改原来变量的值。
(2)指针传参 :其实是传地址,可以修改原来变量的值。

4.函数封装:



写一个比较三个数大小的函数:

#include <stdio.h>
int maxOfThreeNumber(int a, int b, int c)  //形参可以与实参名一样也可以不一样。
{
	int max;
	max = a > b ? a : b;
	max = max > c ? max :c;
	return max;	
}
int main(void)
{
	int x = 10, y = 15, z = 20; 
	printf("%d\n",maxOfThreeNumber(x,y,z));
	return 0;
}


写一个求两数和的函数:

#include <stdio.h>
int sumOfTwoNumber(int a, int b)
{
	int ret;
	ret = a + b;
	return ret;
}
int main(void)
{

	int x = 10, y = 15, z = 20;
	sumOfTwoNumber(10, 15);
	printf("%d\n", sumOfTwoNumber(x,y));
	return 0;
}


打印星星:

int printStar(int n)
{
	int i;
	for (i = 0; i < n; ++i)
	{
		putchar('*');
		
	}
	return ;
	puts("");
	
}


打印100以内可以被三整除的数:

int div3(int n)
{
	return n % 3 == 0;
}

int main(void)
{
	int i;
	for(i = 0;i <= 100;++i)
	{
		if(div3(i))
		{
			printf("%d\n", i);
		}
	}
	return 0;
}


写一个可以判断是否为闰年的函数,和可以判断每年月份有多少天的函数,然后输入年份,月份可以判断此月有多少天:

#include <stdio.h>
int isLeapYear(int year) //可以判断是否为闰年
{

	return (year % 4 == 0 && year % 100 !=0 || year % 400 == 0);
}

int dayOfTheMonth(int year, int month) //可以判断某年的某月有多少天,此函数调用了上面判断是否为闰年的函数;
{
	int day;
	switch(month)
	{
		case 2:
			if(isLeapYear( year))
			{
				day = 29;
			}
			else
			{
				day = 28;
			
			}
			break;
		case 4:
		case 6:
		case 9:
		case 11:
			day = 30;
			break;
		default:
			day = 31;
			break;
	}
	return day;
}

	
int main(void)
{
	int year, month;
	scanf("%d%d", &year, &month);  
	printf("%d\n ", dayOfTheMonth(year, month));
	return 0;
}

方法二:

#include <stdio.h>
int isLeapYear(int year)
{
	return (year % 4 == 0 && year % 100 != 0 || year % 400 == 0);
}

int dayOfTheMonth(int year, int month)
{

	int days[] = {31,0,31,30,31,30,31,31,30,31,30,31};  //存常量在这块效率高,而且下面的判断比较巧妙。
	if(2 == month)   //先判断是否为二月,这样可以省掉许多计算量
	{
		if(isLeapYear(year))
		{
			return 29;
		}
		else
		{
			return 28;
		}
	}

		return days[month - 1];
}

int main(void)
{	
	int year, month;
	scanf("%d%d", &year, &month);
	printf("%d\n", dayOfTheMonth(year, month));
	return 0;
}

//函数参数的传递是从右向左的。

#include<stdio.h>

int fn(int n)
{
	printf("%d\n", n);
	return n;
}

void swap(int a, int b)
{

	int t;
	t = a;
	a = b;
	b = t;
}
int main(void)
{

	int i = 3, j = 5;
	fn(i); //此处可以验证 fn();函数。 这句打印 3
	fn(j); //这句打印 5
	swap(fn(i),fn(j)); //此句先打印 5, 再打印3,可以验证函数传递参数是从右向左的。
	return 0;
}


写一个比较两数大小的函数:
#include <stdio.h>

int compare(int a, int b)  
{

	if(a > b)
	{
		return 1;
	}
	else if (a == b)
	{
		return 0;
	}
	else
	{
		return -1;
	}
}

int main(void)  //此处主要验证下面同一变量再比较中,使用自增运算带来的问题
{

	int i = 2;
	int k;
	k = compare(i, i++);
	printf("%d\n", k);   // k 的结果为 1

	i = 2;
	k = compare(i++, i); //k 的结果为 -1    (结果与预想不同)
	printf("%d\n", k);

	i = 2;
	k = compare(i, ++i);
	printf("%d\n", k);   //k 的结果为  0

	i = 2;
	k = compare(++i, i);
	printf("%d\n", k);   //k 的结果为  0   (结果与预想不同)
}

重点:***分析上面出现的原因是自增运算符的先后没有一个明确的规定,因此每个编译器厂商都是按照自己的理解来定义先后的。
此处是在Linux 平台下运行的结果。换个编译器结果就会发生变化。因此,此代码的移植性就很低,所以写代码时不要这样
写否则可能带来不可预知的后果。



 #include <stdio.h>
 int main(void)
 {
	 char s[1024 * 1024 * 8];  //此处这样写,程序运行时会 ,断片(专业说法程序崩溃),提示为: Segmentation fault (core dumped),  
	 puts(""); 	
	return 0;
	 
 }

分析原因:程序的栈不够用了。栈是内存中开辟的一处空间,在Linux系统环境下,系统会给每个程序的栈划分 7M~8M字节的空间。
此处定义的局部变量就占据了 8M字节的大小 ,当执行 puts("");语句时,程序就会调用 puts();函数 ,这时候就要 ”保护现场“, 去调用函数
等到,调用完后就会返回,此处用于保护现场的指令地址也是要放到栈中的,可是这时候栈已经满了,放不下任何东西了所以会溢出。发生崩溃。



//在Windows下系统一般给一个程序分配 1MB 字节的栈空间



划区大致可以划为五大区:
(1)栈区 :主要用于存放局部变量, 函数内部的形参 ,以及函数调用的返回值。这些占用的内存,会被系统自动回收。
(2)堆区 :
(3)字符常量区 :存放字符串常量 ,如 “Hello”, 不存放’A’,它不是字符串常量。
(4)全局区 :
(5)代码区 :存放二进制指令。



写一个可以计算阶乘的函数,要求不能使用 for();循环, while 循环,等。。。
分析:此种情况一般都是让使用递归函数来实现。
此类函数要注意两点:(1)查找函数结束时的条件。
(2)函数的递归调用。

int factorial(int n)
{
	if(1 == n)   //此处为函数结束的条件
	{
		return 1;
	}
	else
	{
		return factorial(n - 1) * n;  //此处为递归的调用
	
	}

}
int main(void)
{

	int m;
	m = factorial(3);
	printf("%d\n", m);       //相当与  factorial(factorial(factorial(1)-1)-1) * 3  
	return 0;                //结果为: 1 * 2 * 3 

}


汉诺塔问题,按要求完成所需要的次数:

void move(char p1, char p2)
{
	printf("%c->%c\n", p1, p2);
}

void hanoi(int n, char polo1, char polo2, char polo3)
{
	if(1 == n)
	{
		move(polo1, polo3);
		return ;
	}
	else
	{
		hanoi(n -1, polo1, polo3, polo2);
		move(polo1, polo3);
		hanoi(n - 1, polo2, polo1, polo3);
	}
}

int main(void)
{
	hanoi(64, 'A', 'B', 'C');
	return 0;
}


计算出第n项的斐波拉契数字:
分析: 此处可以使用递归算法,
第一步找到退出的条件,当为第一项,第二项时,结果都为1;
第二步函数的递归调用,fib(n -1) + fib(n - 2)

#include <stdio.h>
int fib(int n)
{

	if(1 == n || 2 == n)
	{
		return 1;
	}
	else
	{
		return fib(n - 1) + fib(n - 2);
	}

}
int main(void)
{
	printf("%d\n", fib(5));
	return 0;	
}


用函数写一个数组逆序的功能:

#include <stdio.h>
void reverse(int a[], int len)
{
	int i;
	for(i = 0; i < len / 2; ++i)
	{
		int t;
		t = a[i];
		a[i] = a[len - i - 1];  //此处记得要减一
		a[len - i -1] = t;
	}

}

void printArray(int a[], int len)
{

	int i;
	for(i = 0; i < len; ++i)
	{
		printf("%d, ", a[i]);
	
	}
	puts("\b ");
}

	int main(void)
	{
		int a[] = {1,2,3,4,5,6,7,8,9,0};
		reverse(a, sizeof(a) / sizeof(a[0]));
		printArray(a, sizeof(a) / sizeof(a[0]));
		return 0;
	}


调用函数的方法写选择排序:

#include <stdio.h>
void printArray(int a[], int len)
{
	int i;
	for(i = 0;i < len;++i)
	{
		printf("%d ,", a[i]);
	}
	puts("\b ");
}

void choiceSort(int a[], int len)
{
	int i, j;
	for(i = 0;i < len - 1;++i)
	{
		for(j = i + 1;j < len;++j)
		{
			if(a[i] > a[j])
			{
				int t = a[i];
				a[i] = a[j];
				a[j] = t;
			}
		}
	}
}

int main(void)
{
	int a[] = {1,2,3,4,5,6,7,8,9,0};
	choiceSort(a, sizeof(a) / sizeof(a[0]));
	printArray(a, sizeof(a) / sizeof(a[0]));
	return 0;
}

//函数调用数组时,第一个参数为数组名, 第二个参数为数组长度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值