===========================
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)
如果使用值传递来传递参数,这意味着函数内的代码不能改变用于调用函数的实际参数.