黑马程序员———C语言———【函数指针、指针函数、野指针、内存管理、const关键字】

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------

——————————————————————————————————————————————————————————————————

一、fgets()和fputs()

1、fgets()

(1)比较

该函数时一个文件操作相关的函数

原来接收字符串保存到数组中的方法

char str [ 50 ];

1)scanf("%s",str);//缺点:不能输入空格

2)gets(str);//优点:可以输入空格

//缺点:会有一个警告,不安全的,数组越界。

//比如数组长度是50,此时正好输入50个字符到数组中,就存在问题。因为没有内存存储字符串结束符。

3)fgets()是一个安全的字符串接收函数

char ch[5];//如果使用fgets()此时数组中最多存放4个可见字符。留下1个字符存放字符串结束符\0

(2)使用

1)定义:char * fgets(数组名,数组长度,stdin);

2)注意:当输入的字符串的长度小于数组长度的时候,除了保存字符串结束符,gets()还会接收一个回车,回车再字符串的位置在\0前面。

2、fputs()也是一个文件操作相关的函数

格式:fputs(数组名,stdout);

注意:fputs不会自动换行,也不会进行格式化输出

二、const关键字

1、概念:const是一个类型修饰符,使用const修饰变量可以让变量的值不能改变

2、使用的地方:

(1)修饰变量:被const修饰的变量,变量的值不能被改变,否则编译器报错。

(2)修饰指针变量

1)cosnt修饰的指针变量,指向的变量的值不可变,指向可以变

第一种情况:

第二种情况:

以上两种情况只是int和const的位置互换。但是结果都是一样的。值不可以变,指向可以变。

2)const修饰的指针变量,指向的变量的值可以变,指向不能变

3)const修饰的指针变量,指向的变量的值不能变,指向也不能变

4)记忆技巧:

看const 和 * 的位置

如果const在* 的左侧,表示指针变量指向的变量的值不可以改变,指向可以改变

如果const在* 的右侧,表示指针变量指向的变量的值可以改变,但指向不能改变

如果cosnt出现在* 的两侧,表示都不能改变

(3)修饰数组

(4)强制修改(xcode里a的值还是10,但是*p是100,地址还是a的地址)

、内存管理的概念和内存分区

1、内存分配方式

(1)从静态存储区域分配,内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量

(2)从栈上创建,在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放,栈内存分配运算内置于处理器的指令集中,效率恒高,但是分配的内存容量有限。

(3)从堆上分配,亦称为动态分配,程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用freee或delete释放内存,动态内存的生存期由我们决定,使用非常灵活,但问题也很多。

2、内存的分区

栈:存放程序临时创建的局部变量

堆:存放进程运行中被动态分配的内存段

BSS段:存放程序中未初始化的全局变量和静态变量

数据段:存放程序中已初始化的全局变量和静态变量

代码段:存放程序执行代码的一块内存区域(编译后的代码)

四、常见的动态内存分配函数

(1)malloc

格式:void * malloc(unsigned size);

从内存的堆区分配大小为size个字节的连续的内存空间,如果分配成功,返回内存的首地址,分配失败,返回NULL

如果用malloc申请的内存空间我们不赋值,那么值就是垃圾数(绝大部分都是0)。

使用meset()给malloc申请的空间初始化:

memset(p,'a',16);//值都变成了16

2)calloc()

格式:calloc(块数,长度);

注意事项:它可以自动帮我们初始化为0

3)realloc():给已经存在的内存空间扩充大小

返回值:(新)空间的地址,也有可能是原来的地址。

五、野指针和内存泄露

1、野指针:内存好比作尺子,尺子上0毫米处就是内存0的地址,也就是NULL地址处。这条栓“野指针”的链子就是这个NULL

定义指针变量的同时最好初始化为NULL,用完指针之后也将指针变量的值设为NULL,也就是说除了在使用时,别的时间都把指针栓到0地址处,这样它就老实了2、内存泄露:

int *p定义了一个int类型的指针变量。malloc(100)向内存申请了100个长度的内存空间,被分配的这个内存空间是在堆中。当main函数代码执行完毕后,指针变量p会被内存回收,栈里没有了这个指针变量,可堆中的那个100个空间还在,并且没有人可以调用,这就造成了内存泄露。

3、释放内存空间free()

所以,为了防止内存泄露,我们要在p释放之前,先释放堆里我们申请的这个空间。

怎么释放堆里的空间?用free函数。即free(p)

但是即使我们使用了free函数,在main函数没有运行结束时,当我们再次使用p时,扔可以访问堆中的空间。如下:

main函数没结束之前,p指向的内存空间被释放,p就成了一个野指针,我们需要把野指针“栓”起来,让它老实。如下:

野指针栓上以后,我们再用野指针访问元素,系统就会报错。

————————————————————————————————————————————————————————————————————————————-

一、指针函数

1、概念:返回值是指针的函数就是指针函数。

2、定义:类型说明符 * 函数名(形参表){ return 地址;}

3、代码:返回两个数中大数的地址

以下的写法是错误的,因为被调函数返回的是形参的地址而不是实参的地址。

4、代码联系:

输入1-7的数字,打印出中文星期一到星期日

、函数指针

1、概念:指向函数的指针变量称为“函数指针变量”

2、形式:返回值类型 (*指针变量名)(函数的参数);

3、使用:实现加减乘除

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值