0%

03c_06day

===========================
2022-7-21
===========================

一.温故知新	
    指针
        malloc
    指针的含义 : 指针就是用来存储地址
    NULL
    指针的定义 : 数据类型	指针名	;
                 char *		pc		;
                 char *		pi		;
                 float *	pf		;

指针

    通过sizeof测试
    指针的命名规则和变量的命名规则一致
    int i = 0;
    int *p;

    p = &i;
    *p
    指针运算符
    数据类型	指针名	=	地址	;
    int *		p		=	NULL	;
    int *p;	->	int
    char *p;	->	char
    指针可以做加减法运算
        p+1;	p+=1;	p++;	++p;
    特殊指针
        空类型指针(万能指针)
        空指针
        野指针

    容易混淆的声明
        const	指针
        指针常量
        常量指针
        数组	函数
        指针数组
        数组指针
        指针函数
        函数指针
        函数指针数组
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>
#include <stdlib.h>

int add(int a, int b);//函数的声明

int add(int a, int b)//函数的实现
{
return a + b;
}

int main(int argc, char *argv[])
{
int a = 0, b = 0;
int sum = 0;

scanf("%d-%d", &a, &b);

sum = add(a, b);//函数的调用

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

int max(int , int );//函数的声明

int max(int x, int y)//函数的实现
{
//x > y ? return x : return y;
return x > y ? x : y;
}

int main(int argc, char *argv[])
{
int a = 0, b = 0;
int sum = 0;

scanf("%d-%d", &a, &b);

sum = max(a, b);//函数的调用

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

int isleapyear(int );//函数的声明

int isleapyear(int abc)//函数的实现
{
return (!(abc%4)&&(abc%100)) || (!(abc%400));
}

int main(int argc, char *argv[])
{
int year = 0;
int sum = 0;

scanf("%d", &year);

sum = isleapyear(year);//函数的调用
//如果sum = 1代表是闰年 如果sum = 0代表是平年

sum == 1 ? printf("%d年是闰年!\n", year) : printf("%d年是平年!\n", year);

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

void func(int ,int);

void func(int a, int b)
{
int min = 0, max = 0;
int i = 0, j = 0;

min = a < b ? a : b;
max = a > b ? a : b;

for(i = min; i <= max; i++)
{
for(j = 2; j < i; j++)
{
if(i % j == 0)
break;
}
if(i == j)
printf("%d\t", i);
}
}

int main(int argc, char *argv[])
{
int a = 0, b = 0;

scanf("%d-%d", &a, &b);

func(a, b);//函数的调用
//func()的功能是寻找最小值 - 最大值之间的素数

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

void swap(int ,int);

void swap(int a, int b)
{
int tmp = 0;

printf("swap.交换之前a = %d b = %d\n", a, b);
printf("swap.交换之前a = %p b = %p\n", &a, &b);
tmp = a;
a = b;
b = tmp;
printf("swap.交换之后a = %d b = %d\n", a, b);
printf("swap.交换之后a = %p b = %p\n", &a, &b);
}

int main(int argc, char *argv[])
{
int a = 0, b = 0;

scanf("%d-%d", &a, &b);

printf("main.交换之前a = %d b = %d\n", a, b);
printf("main.交换之前a = %p b = %p\n", &a, &b);

swap(a, b);//通过swap()交换变量a b的值

printf("main.交换之后a = %d b = %d\n", a, b);
printf("main.交换之后a = %p b = %p\n", &a, &b);

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>
#include <stdlib.h>

void swap(int *, int*);

void swap(int *a, int *b)
{
int tmp = 0;

tmp = *a;
*a = *b;
*b = tmp;
}

int main(int argc, char *argv[])
{
int a = 0, b = 0;

scanf("%d-%d", &a, &b);

printf("main.交换之前a = %d b = %d\n", a, b);

swap(&a, &b);//通过swap()交换变量a b的值

printf("main.交换之后a = %d b = %d\n", a, b);

return 0;
}

程序员写C语言程序会经历几个阶段
第一阶段	只写一个.c文件,在.c文件中只写一个main函数
            把所有的功能都放到main函数中
第二阶段	只写一个.c文件,在.c文件中除了有main函数以外
            还会有其他的功能函数的封装
第三阶段	在一个项目工程中存在多个.c或者.h文件
            main.c		存放main函数以及功能函数的调用
            func.c		存放功能函数的实现
            func.h		存放功能函数的声明以及各种定义
            makefile	是一个脚本文件(存放的是编译规则)
第四阶段	把func.c制作成库文件
            动态库和静态库

函数
当写一个C语言程序时,首先需要写的一个函数就是main函数
1.函数的含义
    函数就是一个功能,当调用函数时,会使用这个功能
    printf()	->	打印输出
    scanf()		->	录入
    rand()		->	用来产生随机数
    srand()		->	随机种子
    time()		->	获取时间的描述
    getpid()	->	获取进程ID号
    sleep()		->	秒级延时
    usleep()	->	微秒级延时
    system()	->	调用shell命令
    函数的出现是为了减少代码量,减少代码的冗余
    例子 : printf函数的代码量有100行左右
    如何把一部分的代码封装成一个函数,其实是由程序员决定的
    通过是根据每个函数执行一个特定的功能来进行划分的
2.函数组成部分
    一般来说函数是由三个部分组成的
    1)函数的声明(函数的定义)
        其实就是告诉编译器,函数的名称,函数的返回值
            以及函数的参数
函数的返回值类型 函数名(参数列表);//该处参数指的是形式参数
函数的返回值类型 函数名	(参数列表);
char *			 strcpy (char *dest, const char *src);
void *			 malloc (size_t size);
int				 rand	(void);
void			 srand	(unsigned int seed);
注意 : 
        1>函数名的命名规则和变量的命名规则一致
        2>在写函数的声明时,可以不指定形式参数的名字,
            但是必须要有形式参数的数据类型
    2)函数的实现
        其实就是把函数所代表的功能通过代码进行实现
函数的返回值类型 函数名(参数列表)//该处参数指的是形式参数
{
    功能实现的代码
}
    注意 : 
        1>在写函数的实现时,必须要指定形式参数的名字
    3)函数的调用
        其实就是在代码中使用函数实现的功能
函数名(参数);//该处参数指的是实际参数
形式参数和实际参数是两个不同的内容,可以同名
其实是形式参数来接收实际参数的值的
3.函数的传参
    值传递	: 是把实际参数的值传递给形式参数
            在这种情况下修改形式参数的值不会影响实际参数
        总结: 如果只是想要访问实际参数的值,
                不想修改实际参数的值,那么就使用值传递
        add(); max(); isleapyear(); printf();

    地址传递: 是把实际参数的地址传递给形式参数(指针)
            如果通过形式参数修改指向空间的数据
            会改变实际参数的值
        总结: 如果想要通过形式参数修改实际参数的值
            那么就用地址传递
        swap(); scanf();
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>
#include <stdlib.h>

void print(int);
void change(int *);

void print(int a)
{
printf("a = %d\n", a);
}

void change(int *a)
{
scanf("%d", a);
}

int main(int argc, char *argv[])
{
int a = 9527;

print(a);//通过print函数打印变量a的值

change(&a);//通过change函数改变a的值

print(a);//通过print函数打印变量a的值

return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
int i = 9527;
int *p = &i;

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

return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
printf("sizeof(char **) = %ld\n",sizeof(char **));
printf("sizeof(short **) = %ld\n",sizeof(short **));
printf("sizeof(int **) = %ld\n",sizeof(int **));
printf("sizeof(long **) = %ld\n",sizeof(long **));
printf("sizeof(float **) = %ld\n",sizeof(float **));
printf("sizeof(double **) = %ld\n",sizeof(double **));

return 0;
}
/* =========================== 作业: 1.把今天讲过的内容完完整整的复习一遍 2.最少把<猜数游戏>和<口算卡>改为多函数的版本 =========================== 二级指针 1.二级指针的含义 只要是指针,那就是用来存储地址的 一级指针是用来保存变量的地址的 (可以使用一级指针操控变量) 二级指针是用来保存一级指针的地址的 (可以使用二级指针操控一级指针) 2.二级指针的定义 int i ; 数据类型 指针名 ; int * p ; int ** pp ; 3.通过sizeof测试占用存储空间的大小 无论何种类型的二级指针在我当前的机器环境中, 占用空间大小都是8个字节 4.二级指针的命名规则和变量的命名规则一致 5.使用二级指针
1
2
3
4
5
6
7
8
9
10
名	i		p		pp

100 0x1000 0x2000
i p pp
*p *pp
**pp
0x1000 0x2000 0x3000
&i &p &pp
p pp
*pp
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
int i = 100;
int *p = &i;
int **pp = &p;

printf("i = %d\n", i);
printf("*p = %d\n", *p);
printf("**pp = %d\n", **pp);
printf("====================\n");
printf("&i = %p\n", &i);
printf("p = %p\n", p);
printf("*pp = %p\n", *pp);
printf("====================\n");
printf("&p = %p\n", &p);
printf("pp = %p\n", pp);
printf("====================\n");
printf("&pp = %p\n", &pp);

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

int main(int argc, char *argv[])
{
int i = 100;
int *p = &i;
int **pp = &p;

printf("&p = %p\n", &p);
printf("pp = %p\n", pp);

pp++;

printf("&p = %p\n", &p);
printf("pp = %p\n", pp);

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

void change(int **, int *);

void change(int **p, int *b)
{
*p = b;
}

int main(int argc, char *argv[])
{
int a = 100, b = 200;
int *p = &a;

printf("*p = %d p = %p\n", *p, p);

//change(p, &b);
change(&p, &b);//通过change函数把指针p指向b变量

printf("*p = %d p = %p\n", *p, p);

return 0;
}
随机函数 rand(); //功能:就是用来产生随机数的 rand() % 1000; //[0 ~ 999] rand() % 100 - 50;//[-50 ~ 49] srand(); //功能:可以保证每一次产生的随机数可变 srand函数在调用时需要有可变的因子 time(NULL); //时间种子 getpid(); //进程种子
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
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <unistd.h>

void func(void);

void func(void)
{
int T = 0;//存储随机出的数字
int guess = 0;//存储玩家猜的数字
int num = 1;

srand(getpid());//随机种子

T = rand() % 10;

for(num = 1; ; num++)
{
scanf("%d", &guess);
if(T > guess)
printf("[%d] Small!\n", num);
else if(T < guess)
printf("[%d] Big!\n", num);
else
{
printf("[%d] Bingo!\n", num);
break;
}
}
}

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

return 0;
}