看懂程序 : 流程 功能 试数

求一元二次方程组(第一个小程序)

 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
26
27
28
29
30
31
32
33
34
35
36
37
# include <stdio.h>
# include <math.h>

int main(void)
{
	//把三个系数保存到计算机中

	int a = 0;  //=不表示相等,表示赋值
	int b = 0;
	int c = 0;
	printf("输入一元二次方程(如:3x^2+4x+5):");
	scanf_s("%dx^2+%dx+%c", &a, &b, &c);
	double delta; //delt存放的是 b*b - 4*a*c
	double x1; //存放一元二次方程的其中一个解
	double x2; //存放一元二次方程的其中一个解

	delta = b*b - 4 * a*c;

	if (delta > 0)
	{
		x1 = (-b + sqrt(delta)) / (2 * a);
		x2 = (-b - sqrt(delta)) / (2 * a);
		printf("该一元二次方程有两个解, x1 = %f, x2 = %f\n", x1, x2);
	}
	else if (delta == 0)
	{
		x1 = (-b) / (2 * a);
		x2 = x1;  //右边赋给左边
		printf("该一元二次方程有一个唯一解, x1 = x2 = %f\n", x1);
	}
	else
	{
		printf("无解\n");
	}

	return 0;
}

常量在c语言中如何表示

 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
26
27
28
29
30
31
32
33
34
# include <stdio.h>

int main(void)
{
	int i = 23; //十进制
	int j = 027; //八进制
	int k = 0x17; //十六进制
	printf("i = %d\n", i);//十进制
	printf("i = %o\n", i);//八进制
	printf("i = %x\n", i);//十六进制

	printf("j = %d\n", j);
	printf("j = %o\n", j);
	printf("j = %x\n", j);

	printf("k = %d\n", k);
	printf("k = %o\n", k);
	printf("k = %x\n", k);

	float y = 3.2e3;// 3.2*10^3=3200.000 000
	printf("%f\n", y);
	
	char ch = 's';//字符  单引号 's'   //字符串 双引号  "sa"  //"s"  代表  's'与'/0' 的组合
	printf("%c\n", ch);

	int x = 47;  //100是十进制
	printf("%x\n", x);  //输出结果是:  2f
	printf("%X\n", x);	//输出结果是:  2F
	printf("%#X\n", x);	//输出结果是:  0X2F  %#X推荐使用
	printf("%#x\n", x);	//输出结果是:  0x2f
	//printf  int %d  char %c  flaot %f double %lf  long int %ld

	return 0;
}

流程控制

分类:顺序 选择(if 与switch) 循环 (for while )
if 空语句问题 if(); 非空语句if() A;

求1到任意一个整数之间的数的奇偶数之和sum1sum2、奇偶数之个数cnt1cnt2、奇偶数之平均值avg1avg2

 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//求1到任意一个整数之间的数的奇偶数之和sum1sum2、奇偶数之个数cnt1cnt2、奇偶数之平均值avg1avg2
#include <stdio.h>

int main(void)
{
	int i;
	int sum1 = 0;
	int sum2 = 0;
	int cnt1 = 0;
	int cnt2 = 0;
	float avg1;
	double avg2;
	int len = 0;
	printf("请输入任意整数:");
	scanf_s("%d", &len);
	for (i = 1; i <= len; ++i)
	{
		if (i % 2 == 1)
		{
			sum1 += i;//sum = sum + i;
			++cnt1;
		}
		else
		{
			sum2 += i;
			++cnt2;
		}

	}
	avg1 = (float)sum1 / cnt1;
	avg2 = sum2 / cnt2;

	printf("%d\n", sum1);
	printf("%d\n", sum2);
	printf("%d\n", cnt1);
	printf("%d\n", cnt2);
	printf("%f\n", avg1);
	printf("%lf\n", avg2);
	return 0;
}

浮点数存储所带来的问题

 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
* C语言中判断浮点数是否等于0
*/
# include <stdio.h>
# include <math.h>
# define FLOAT_EPS 1e-6
# define DOUBLE_EPS 1e-15


int main(void)
{
	float f1 = 0.000001;
	float f2 = 0.001;
	double d1 = 0.00001;
	double d2 = 0.00001;

	//判断浮点数是否等于0
	//1、单精度浮点数
	if (fabs(f1) <= FLOAT_EPS)
	{
		printf("%f为0\n", f1);
	}
	else
	{
		printf("%f不为0\n", f1);
	}
	//2、双精度浮点数
	if (fabs(d1) <= DOUBLE_EPS)
	{
		printf("%lf为0\n", d1);
	}
	else
	{
		printf("%lf不为0\n", d1);
	}
	//判断两个浮点数是否相等
	//1、单精度浮点数
	if (fabs(f1 - f2) <= FLOAT_EPS)
	{
		printf("%f 和 %f 相等\n", f1, f2);
	}
	else
	{
		printf("%f 和 %f 不相等\n", f1, f2);
	}
	//2、双精度浮点数
	if (fabs(d1 - d2) <= DOUBLE_EPS)
	{
		printf("%lf 和 %lf 相等\n", d1, d2);
	}
	else
	{
		printf("%lf 和 %lf 不相等\n", d1, d2);
	}
	return 0;
}

多个for循环的嵌套使用

 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
26
27
28
29
30
31
32
33
34
35
# include <stdio.h>

int main(void)
{
	int i, j, k;

	for (i = 0; i < 2; ++i)
		for (j = 0; j < 3; ++j)
		{
			printf("aaa!\n");
			printf("bbb!\n");
			for (k = 0; k < 4; ++k)
			{
				printf("ccc!\n");
			}
		}


	return 0;
}
//for (1; 2; 3)
// for (4; 5; 6) 
//   A;
//   B;
//总共两个语句一个内部一个外部:1.// for (4; 5; 6) //   A;  2.  B;
//执行顺序:[1-->2 (-->4-->5-->A-->6) -->5成立-->A-->6-->5不成立   -->3]
//[-->2成立(-->4-->5-->A-->6-->5不成立-->3]  -->2不成立-->B

//for (1; 2; 3)
//for (4; 5; 6)
//{
//	A;
//	B;
//}
//总共一个语句 for只控制了一个语句://for (4; 5; 6){A;B;}

自增自减比较

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# include <stdio.h>

int main(void)
{
	int i;
	int j;
	int k;
	int m;

	i = j = 3; //等价于 i = 3;  j = 3;
	k = i++;//k=i ;i=i+1
	m = ++j;//j=j+1;m=j

	printf("i = %d, j = %d, k = %d, m = %d\n", i, j, k, m);

	return 0;
}

三目运算符

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# include <stdio.h>

int main(void)
{
	int i;

	i = (6> 2 ? 5 : 1); //if (6>2)5;else 1
	printf("%d\n", i);//5

	return 0;
}

逗号表达式

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# include <stdio.h>

int main(void)
{
	int i;
	int j = 2;

	i = (j++, ++j, j + 2, j - 3);// 3  4 4-3=1
	printf("%d\n", i);

	return 0;
}

for与while相互转换

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# include <stdio.h>

int main(void)
{
	int sum = 0;
	int i;

	//for (i = 1; i < 101; ++i)
	//{
	//	sum = sum + i;
	//}
	//等价于
	i = 1;
	while (i<101)
	{
		sum = sum + i;
		++i;//15行与16行位置不能换
	}
	printf("sum = %d\n", sum);

	return 0;
}

判断一个数是否为回文数

 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
26
27
28
29
30
# include <stdio.h>

int main(void)
{
	int val; //存放待判断的数字
	int m;
	int sum = 0;

	printf("请输入您需要判断的数字:  ");
	scanf("%d", &val);
	
	m = val;
	while (m)
	{
		sum = sum * 10 + m%10;
		m /= 10; 
	}

	if (sum == val)
		printf("Yes!\n");
	else
		printf("No!\n");

	return 0;
}
//123试数
//》1 sum = 0* 10 +123 % 10=3        m=123/10=12
//》2 sum = 3 * 10 + 12 % 10 =32     m = 12 / 10 = 1
//》3 sum = 32 * 10 + 1 % 10 = 321   m = 1 / 10 =0
//》4 m=0 退出循环

求斐波那契数列

 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
//循环法求斐波那契数列
#include <stdio.h>
int main(void)
{
	long long  n = 0;
	long long  f3 = 0, f2 = 1, f1 = 0;
	long long  total = 0;
	printf("请输入斐波那契数列列项数n:");
	scanf_s("%d", &n);
	printf("斐波那契数列为:");
	while (n > 0)
	{
		n = n - 1;
		f1 = f2;
		f2 = f3;
		f3 = f1 + f2;
		total = total + f3;
		printf("%-2d", f3);//指定显示宽度 

	}
	printf("\n");
	printf("第n项为:%d\n", f3);
	printf("前n项和为:%d\n", total);//只能算到n=44 
	return 0;

}

//递归法求斐波那契数列
//#include <stdio.h>
//int fib(long long);
//int main(void)
//{
//	long long n = 0;
//	long long total = 0;
//	long long i;
//	printf("请输入斐波那契数列列项数n:");
//	scanf_s("%d", &n);
//	printf("斐波那契数列为:");
//	for (i = 1; i <= n; ++i)
//	{
//		printf("%2d.", fib(i));
//		total = total + fib(i);
//	}
//	printf("\n");
//	printf("第n项为%d\n", fib(i));
//	printf("前n项和为:%d\n", total);
//	return 0;
//}
//int fib(long long n)
//{
//	if (n == 1 || n == 2)
//	{
//		return 1;
//	}
//	else
//		return fib(n - 1) + fib(n - 2);
//}
//总结:普通递归耗时非常长,远不如循环。

switch(val) {case 1: 语句1;case 2:语句2} case 程序的入口一旦找到就依次向下执行 不在判断其他case 除非break。

 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
26
27
# include <stdio.h>

int main(void)
{
	int val;

	printf("请输入您要进入的楼层: ");
	scanf_s("%d", &val);

	switch (val)
	{
	case 1:
		printf("1层开!\n");
		break;
	case 2:
		printf("2层开!\n");
		//break;
	case 3:
		printf("3层开!\n");
		break;
	default:
		printf("没有盖到这一层!\n");
		break;
	}

	return 0;
}

break 和continue

break 用于for与switch都是终止离break最近的for与switch .break不用于if
continue 用于跳过本次循环余下的语句 直接再去判断while 或者 for中的判断

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# include <stdio.h>

int main(void)
{
	int i;
	char ch;

	scanf_s("%d", &i);
	printf("i = %d\n", i);


	while ((ch = getchar()) != '\n')
		continue;
	int j;
	scanf_s("%d", &j);
	printf("j = %d\n", j);

	return 0;
}

数组

为了解决大量同类型数据存储问题

函数

函数体现了是面向过程还是面向对象
c语言是面向过程 学此 能更好的去理解c++中 函数 面向对象
函数是c语言基本单位,类是c++基本单位。

  • 为什么要函数:避免了重复性操作 有利于程序模块化
    函数相当于一个工具
  • 什么是函数:
    逻辑上:能够完成特定功能的独立代码块
    物理上:能接受数据处理数据返回结果
  • #include <>“” 区别 :#include< >编译程序会先到标准函数库中调用文件。 #include“ ”编译程序会先从当前目录中调用文件。
  • return与break的区别;return终止函数 break终止循环。
  • 函数的分类:库函数与用户自定义函数 传值函数与传地址函数
  • 函数的声明与定义:声明不开辟内存且可以不写形参名 定义开辟内存且必须有形参名
  • 如何合理设计函数,函数功能单一化模块化 方便使用。

判断是否为素数

 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
26
27
28
29
30
31
32
33
34
35
#include <stdio.h>
bool f_prime(int);
int main(void)
{
	int n;
	printf("输入一个数判断是否为素数:");
	scanf_s("%d", &n);
	if (f_prime(n))
	{
		printf("yes");
	}
	else
	{
		printf("no");
	}
	return 0;
}
bool f_prime(int val)
{
	int i;
	for (i = 2; i < val; ++i)
	{
		if (val%i == 0)
			break;
	}
	if (val == i)
	{
		return true;
	}
	else
	{
		return false;
	}

}

变量的作用域和存储方式

  • 局部变量:局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。—–(放在)栈区

  • 全局变量:全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以 作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern关键字再次声明这个全局变量。—–(放在)静态区也称全局数据区

  • 静态变量:1.静态局部变量2.静态全局变量 —–(放在)静态区也称全局数据区

静态局部变量:静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。

静态全局变量:静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。
* 总结:把局部变量改变为静态局部变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态全局变量后是改变了它的作用域, 限制了它的使用范围。
* 栈区 堆区 全局数据区(静态区) 常量区 代码区

动态变量在子程序中,每次调用都会从它的初始值开始调用,而不管他在函数中经历了什么变化;静态变量会从变化后的值继续改变。 —–存储在内存出栈数据区

 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
26
27
28
 #include <stdio.h>

void fun()
{
	int j = 0;
	j++;
	printf("%d", j);
}

void fun1()
{
	static int j = 0;
	j++;
	printf("%d", j);
}

void main()
{
	int i;
	for (i = 0; i < 5; i++)
		fun();//输出结果为11111

	printf("\n");

	for (i = 0; i < 5; i++)
		fun1();//输出结果为12345
	printf("\n");
}

指针

经典指针程序

 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include "stdio.h"

void huhuan(int*, int*);
int b = 5;//全局变量

int main()
{
	int a = 3;
	huhuan(&a, &b);
	printf("%d,%d", a, b); /*3,3*/
	return 0;
}

void huhuan(int* x, int* y)
{
	printf("%d", *y);/* 5*/
	int *t=&b;// t指向b  y 也指向b
	printf("%d", *y); /*5*/

	*t = *x;// *t改变 那么此时*y 也改变了 
	printf("%d", *y); /*3*/
	*x = *y;
	printf("%d\n", *y);/* 3*/
	*y = *t;

	return;

}

# include <stdio.h>

void f(int * q) //q是p的一份拷贝 p与q 指向同一个地方 都指向了a的地址  *q=a=*p
{
	*q = 200;
}

int main(void)
{
	int a = 5;
	int * p = &a;
	printf("%d\n", *p);
	*p = 15;
	printf("%d\n", *p);
	f(p);  //p是int *类型
	printf("%d\n", *p);
	return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include "stdio.h"

void huhuan(int*x, int*y);

int main()
{
	int a = 3;
	int b = 5;
	huhuan(&a, &b);
	printf("%d,%d\n", a, b);//这里并没有改变 还是3 5
	return 0;
}

void huhuan(int* x, int* y)
{
	printf("%d,%d\n", *x, *y) //3 5
	int *t; 
	t = x;
	x = y;
	y = t;
	printf("%d,%d\n", *x, *y);//5 3 只是把放在指针变量x与y中的 a与b变量的地址交换了位置 a与b变量本身所存放的值没有改变
	return;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "stdio.h"

void huhuan(int*x, int*y);

int main()
{
	int a = 3;
	int b = 5;
	huhuan(&a, &b);
	printf("%d,%d\n", a, b); //该变了
	return 0;
}

void huhuan(int* x, int* y)
{
	int t;
	t = *x;
	*x = *y;
	*y = t;  
	printf("%d,%d\n", *x, *y); // *x==a  *y==b a与b变量本身所存放的值发生改变
	return;
}

指针和数组(数组的升级是容器)

指针和一维数组

 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
26
27
28
29
30
#include <stdio.h>
int main(void)
{
	int a[3] = {5,2,7};
	int b[4][5];
	int i;

	printf("%#x\n", b[0][0]);
	printf("%#x\n", b);//二维数组不是
	printf("%#x\n",&a[0]);// &a[0]==a
	printf("%#x\n", a); //9行与10行输出结果一样 一维数组名a是一个指针常量 存放的是数组第一个元素的地址

	printf("%d\n", *a);//*a==a[0]
	printf("%d\n", *(a+2)); //*(a+1)==a[0+1]==a[1]
	printf("%d\n", *a + 1);// *a + 1==a[0]+1

	for (i = 0; i < 3; ++i)
	{
		printf("%d", a[i]);
		
	}
	printf("\n" );
	for (i = 0; i < 3; ++i)
	{
		printf("%d", *(a + i));//a[i]==*(a + i)

	}
	
	return 0;
}
 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//指针与数组
#include<stdio.h>
int main()
{
	int x[5] = { 3, 5, 79, 4, 9 };
	int *a = x;
	//printf("%-2d", *x);//a[0] 3
	//printf("%2d", *a);
	//printf("%2d", x[0]);
	//printf("%2d", a[0]);
	//printf("\n");

	//printf("%-2d", *x+1);//a[0]+1=4
	//printf("%2d", (*x)+1);//a[0]+1=4
	//printf("%2d", *(x+ 1));//a[1]  5
	//printf("%2d", *(x + 2));//a[2] 79
	//printf("\n");

	printf("%d", *a + 1);//a[0]+1=4
	printf("%2d", (*a) + 1);//a[0]+1=4
	printf("%2d", *(a + 1));//a[1]  5
	printf("%2d", *(a + 2));//a[2] 79//为什么会挨在一起了输出后
	printf("\n");

	//printf("%-2d", *a++);//*a=3 *(a=a+1)=5
	//printf("%2d", *a); //5
	//printf("%2d", (*a)++);//*a=5  *a+1=5+1=6
	//printf("%2d", *a);//6
	//printf("\n");

	//printf("%2d", *(a++));//3
	//printf("%2d", *a);//5
	//printf("\n");

	//printf("%-2d", ++*a);//4
	//printf("%2d", ++(*a));//4  5
	//printf("\n");

	//printf("%-2d", *++a);//5
	//printf("%2d", *(++a));//5  79
	//printf("\n");
	//


	return 0;
}

指针和二维数组

指针变量的运算

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
指针变量只能相减  且两个指针变量指向同一块连续存储空间不同存储单元
# include <stdio.h>

int main(void)
{
	int i = 5;
	int j = 10;
	int * p = &i;
	int * q = &j;
	/*int a[5];
	p = &a[1];
	q = &a[4];*/
	printf("p和q所指向的单元相隔%d个单元\n", q-p);

	//p - q 没有实际意义

	return 0;
}

实参与形参是否是同一个变量 与 没有指针只能返回一个值

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# include <stdio.h>

int  f(int i)
{
	i = 99;
	return i;
}

int main(void)
{
	int i = 6;
	printf("i = %d\n", i);
	f(i);
	printf("i = %d\n", i);
	i=f(i);
	printf("i = %d\n", i);
	return 0;
}

多级指针

 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
26
27
28
# include <stdio.h>

int main(void)
{
	int i = 10;
	int * p = &i;  //p只能存放int类型变量的地址
	int ** q = &p;  //q是int **类型, 所谓int **类型就是指q只能存放int *类型变量的地址, 	
	int *** r = &q;  //r是int ***类型, 所谓int ***类型就是指r只能存放int ** 类型变量的地址, 

	//printf("i = %d\n", ***r); //i 10
	//printf("i = %d\n", **q);
	//printf("i = %d\n", *p);

	//printf(" %#x\n", **r);// p
	//printf(" %#x\n", *r);//q
	//printf(" %#x\n", r);//r

	printf("%#x\n", i);//以十六进方式制输出i的值

	printf("%#x\n", &i);//输出变量i的地址
	printf("%#x\n", &*p);//指针变量p所指向变量i的地址 *p==i
	printf("%#x\n", p);//指针变量p所保存的地址 既是变量i的地址
	printf("%#x\n", **r);// **r==p

	printf("%#x\n", &p);//指针变量p本身的地址
	printf("%#x\n", &**r);// **r==p
	return 0;
}

动态分配内存(动态数组)

malloc用法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
由于malloc()返回的是第一个字节的地址,所以malloc前面的强制转换(int*)代表了返回的就是4个字节的地址
# include <stdio.h>
# include <malloc.h>

void f(int * q)
{
	//*p = 200; //error
	//q = 200;
	//**q = 200;  //error
	*q = 200;
	free(q);  //把q所指向的内存释放掉  本语句必须的注释掉,否则会导致第20行的代码出错
}

int main(void)
{
	int * p = (int *)malloc(sizeof(int)); //sizeof(int)返回值是int所占的字节数
	*p = 10;

	printf("%d\n", *p);  //10
	f(p);  //p是int *类型
	printf("%d\n", *p);  //200    第20行

	return 0;
}

动态一维数组

 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
26
27
28
29
30
 #include <stdio.h>
 #include <malloc.h>

int main(void)
{
	/*	int a[5];*/ //如果int占4个字节的话,则本数组总共包含有20个字节,每四个字节被当做了一个int变量来使用
	int len;
	int * pArr;
	int i;

	//动态的构造一维数组
	printf("请输入你要存放的元素的个数: ");
	scanf_s("%d", &len);
	pArr = (int *)malloc(4 * len);  //第12行  本行动态的构造了一个一维数组, 该一维数组的产度是len, 该数组的数组名是pArr, 该数组的每个元素是int类型  类似于 int pArr[len];

	//对一维数组进行操作,  如:对动态一维数组进行赋值
	printf("输入数组元素元素以空格分开:");
	for (i = 0; i < len; ++i)
		scanf_s("%d", &pArr[i]);

	//对位一维数组进行输出
	printf("一维数组的内容是:\n");
	for (i = 0; i < len; ++i)
		printf("%d\n", pArr[i]);

	free(pArr); //释放掉动态分配的数组


	return 0;
}

动态内存与静态内存的区别:
* 静态内存(数组)函数的调用 —–栈 先进后出
* 动态内存(malloc) —– 堆 顺序随意 堆总是一棵完全二叉树。
* 堆栈就是栈 栈不是堆 堆不是栈
* (堆,栈,队列的区别)[https://www.cnblogs.com/guoxiaoyan/p/8664150.html]
* (深入理解堆与栈 )[https://blog.csdn.net/u014608280/article/details/82218079]

结构体

 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# include <stdio.h>
# include <malloc.h>

struct Student
{
	int age;
	float score;
	char name[100];
};

int main(void)
{
	int len;
	struct Student * pArr;
	int i, j;
	struct Student t;


	//动态的构造一维数组
	printf("请输入学生的个数:\n");
	printf("len = ");
	scanf("%d", &len);
	pArr = (struct Student *)malloc(len * sizeof(struct Student));

	//输入
	for (i = 0; i < len; ++i)
	{
		printf("请输入第%d个学生的信息:\n", i + 1);
		printf("age = ");
		scanf("%d", &pArr[i].age);

		printf("name = ");
		scanf("%s", pArr[i].name);  //name是数组名,本身就已经是数组首元素的地址, 所以pArr[i].name 不能改成 &pArr[i].name

		printf("score = ");
		scanf("%f", &pArr[i].score);
	}

	//按学生成绩升序排序 冒泡算法
	for (i = 0; i < len - 1; ++i)
	{
		for (j = 0; j<len - 1 - i; ++j)
		{
			if (pArr[j].score > pArr[j + 1].score) //>升序 <降序
			{
				t = pArr[j];
				pArr[j] = pArr[j + 1];
				pArr[j + 1] = t;
			}
		}
	}

	printf("\n\n学生的信息是:\n");
	//输出
	for (i = 0; i < len; ++i)
	{
		printf("第%d个学生的信息是:\n", i + 1);
		printf("age = %d\n", pArr[i].age);
		printf("name = %s\n", pArr[i].name);  //name是数组名,本身就已经是数组首元素的地址, 所以pArr[i].name 不能改成 &pArr[i].name
		printf("score = %f\n", pArr[i].score);

		printf("\n");
	}

	return 0;
}

枚举

定义:把一个事物所有可能的取值一一列举出来 特点:安全限制了取值范围 但麻烦

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# include <stdio.h>

//只定义了一个数据类型,并没有定义变量, 该数据类型的名字是 enum WeekDay
enum WeekDay
{
	MonDay=1, TuesDay, WednesDay, ThursDay, FriDay, SaturDay, SunDay
};

int main(void)
{
	//int day; //day定义成int类型不合适
	enum WeekDay day = SunDay;
	printf("%d\n", day);

	return 0;
}

位运算

1
2
3
4
5
6
& 按位与
| 按位或
~ 取反
^ 按位异或
<< 按位左移
>>按位右移

null的含义

字符串结束标记符’\0’
空指针null :null是内存单元编号零 是个地址 计算机规定以零位编号的存储单元不可读不可写 一般用于计算机中断系统使用

零散笔记

指针与数组 指针与结构体 指针与指针(链表)
结构体–类 malloc–new
结构体面向对象面向过程连接

 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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# include <stdio.h>
# include <malloc.h>

struct Student
{
	int age;
	float score;
	
};
int len;
struct Student * pArr,t;
int i,j;
struct Student *creat(void);
int show(void);
int sort();
int main(void)
{
	struct Student * ps;
	ps = creat();
	show();
	sort();

	return 0;
}
struct Student *creat(void)
{



	//动态的构造一维数组
	printf("请输入学生的个数:\n");
	printf("len = ");
	scanf_s("%d", &len);
	pArr = (struct Student *)malloc(len * sizeof(struct Student));

	//输入
	for (i = 0; i < len; ++i)
	{
		printf("请输入第%d个学生的信息:", i + 1);
		printf("age = ");
		scanf_s("%d", &pArr[i].age);

		printf("score = ");
		scanf_s("%f", &pArr[i].score);
	}
	return pArr;
}

int show()
{
	printf("\n\n学生的信息是:\n");
	//输出
	for ( i = 0; i < len; ++i)
	{
		printf("第%d个学生的信息是:\n", i + 1);
		printf("age = %d\n", pArr[i].age);
		printf("score = %f\n", pArr[i].score);

		printf("\n");
	}
	return 0;
}
int  sort()
{
	for (i = 0; i < len - 1; ++i)
	{
		for (j = 0; j<len - 1 - i; ++j)
		{
			if (pArr[j].score > pArr[j + 1].score) //>升序 <降序
			{
				t = pArr[j];
				pArr[j] = pArr[j + 1];
				pArr[j + 1] = t;
			}
		}
	}
	show();
	return 0;
}