0%

03c_point_and_func

===========================
2022-8-1
===========================

1.指针

使用指针的用处

        程序员通过指针,可以简化一些 C 语言编程任务的执行,还有一些任务,如动态内存分配
        大家都知道每一个变量都在内存中占用相应的存储空间,
动态内存分配的函数	malloc calloc realloc free
编程人员来讲
1.谁打开,谁关闭	文件IO
2.谁开辟,谁释放	动态内存
3.谁创建,谁销毁	链表
4.谁加锁,谁解锁	线程

        每一个内存位置都可以使用连字号(&)运算符访问的地址,它表示了在内存中的一个地址
    什么是指针
        其实指针从某种意义上来讲是一个变量,其值为另一个变量的地址,即内存位置的直接地址.
        就像普通的变量一样,必须在使用指针之前,对其进行定义.
        指针的定义一般形式为:type *pointer-name;
        无论何种类型的指针在内存中都占用8个字节空间(相对于64bit操作系统而言)
        不同数据类型的指针之间的相同点是都是用来存储地址的.
        不同数据类型的指针之间唯一的不同是,指针所指向的变量的数据类型不同.

如何使用指针?

        使用指针时会频繁进行以下几个操作:
int a;
        定义一个指针变量					int *p;
        把变量地址赋值给指针				p = &a;
        访问指针变量中可用地址的值			printf(“p = %p\n”, p);
        这些操作是需要通过使用运算符 * 来访问的

指向NULL的指针(空指针) int *p = NULL;//NULL ASCII 0 0x0

        在指针初始化的时候,如果没有确切的地址可以赋值,为指针赋一个 NULL 值
        是一个良好的编程习惯.赋为 NULL 值的指针被称为空指针.
        在写C语言程序时不允许访问地址为 NULL 的内存,因为该内存是操作系统保留的
        然而,内存地址 NULL 有特别重要的意义,它表明该指针不指向一个可操作的内存位置.
int a;
int *p = NULL;
p = &a;
*p = 100;
程序编译时不会报错报警告,但是程序执行时会报段错误(编译器不检查段错误)
if(p == NULL)
printf(“p是一个空指针!\n”);

野指针(没有对象)

        野指针指向一个已删除的对象或申请访问受限内存区域的指针.
        与空指针不同,野指针无法通过简单地判断是否为 NULL 避免,
        而只能通过养成良好的编程习惯来尽力减少.
        对野指针进行操作很容易造成程序错误.
        程序编译时不会报错报警告,程序执行时也不会报段错误
        int *p = NULL;
        p = malloc(sizeof(int));
        使用
        free(p);
        p = NULL;//可以先把野指针变成空指针,然后可以避免程序执行时不会报错

万能指针

    可以保存任意类型的地址

2.函数

什么是函数

        函数是一组一起执行一个任务的语句.每个 C 程序都至少有一个函数,
        即主函数 main() 所有简单的程序都可以定义其他额外的函数.
        程序员可以把代码划分到不同的函数中.
        如何划分代码到不同的函数中是程序员自己来决定的,但在逻辑上,
        划分通常是根据每个函数执行一个特定的任务来进行的.
        函数声明告诉编译器函数的名称\返回类型和参数.函数定义提供了函数的实际主体。
    

函数的声明

        函数声明会告诉编译器函数名称及如何调用函数.
        函数声明包括以下几个部分:
        return_type		function_name	(parameter list)	;//形式参数 形参
        int				max			(int a, int b)		;
int				add				(int a, int b)		;
Void			swap			(int *a, int *b)	;
        在函数声明中,参数的名称并不重要,只有参数的类型是必需的
        int max(int, int);

函数的实现

        return_type		function_name	(parameter list)//形式参数 形参
        {
   			body of the function
        }
int				max			(int a, int b)
{
return a > b ? a : b;
}
int				add				(int a, int b)
{
return a + b;
}




void		swap	(int *a, int * b)
{
int c;
c = *a;
*a = *b;
*b = c;
}

函数的调用

        当实现函数的功能时,会写出函数要做什么,然后通过调用函数来执行已写好的功能.
        当程序调用函数时,程序控制权会转移给被调用的函数.
        被调用的函数执行函数主体的内容,当函数的返回语句被执行时,
        或到达函数的结束括号时,会把程序控制权交还给主程序.
        调用函数时,传递所需参数,如果函数返回一个值,则可以在调用时用变量来存储返回值.
        function_name	(parameter list);//实际参数 实参
max			(13, 7);
add				(13, 7);		
swap			(&a, &b);
    在 C 语言中,函数由一个函数头和一个函数主体组成.下面列出一个函数的所有组成部分:
        返回类型 : 一个函数可以返回一个值.return_type 是函数返回的值的数据类型.
            有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void.
        
        函数名称 : 这是函数的实际名称.也是函数的入口
    	
        参数 : 参数就像是占位符.当函数被调用时,程序员需要向参数传递一个值,
            这个值被称为实际参数.参数列表包括函数参数的类型\顺序\数量.
            参数是可选的,也就是说,有些功能函数可能不需要参数.
    	
        函数主体 : 函数主体包含一组定义函数执行任务的语句.
    
    函数参数
        如果函数要使用参数,则必须在函数声明时定义参数变量,这些变量称为函数的形式参数.
        形式参数就像函数内的其他局部变量,在进入函数时被创建,退出函数时被销毁.
    
    当调用函数时,有两种向函数传递参数的方式:
        值传递 : 该方法把参数的实际值复制给函数的形式参数,在这种情况下
                修改函数内的形式参数不会影响实际参数。
swap(a, b)
        地址传递 : 通过指针传递方式,形参为指向实参地址的指针,
                当对形参的指向操作时,就相当于对实参本身进行的操作。
swap(&a, &b)
        如果使用值传递来传递参数,这意味着函数内的代码不能改变用于调用函数的实际参数.