C语言学习高级001-C语言补充01

146 阅读5分钟

1、void关键字可以直接写在函数参数括号内,表示函数没有参数,void可以用在函数返回值,但是void不能直接用来定义变量名。
2、sizeof用法:sizeof(变量) sizeof 变量 sizeof(类型)
3、sizeof 数组名返回的是整个数组的大小,但是sizeof 指针变量返回的是指针变量本身的大小,不是指针指向的变量的大小,32位系统上指针变量大小一般是4。所以数组名做函数实参的时候,形参是一个指针,这个时候通过sizeof形参获取不到数组大小,还是要单独传一个数组长度数据给函数。
4、堆中分配内存的三个函数:malloc、calloc、recalloc:
都需要手动free手动释放。
malloc:申请一个指定大小连续的内存块,不会初始化,直接使用可能得到错误的数据,所以一般用于不用初始化的场景。返回指向内存的指针。
calloc:申请指定个数和指定每个大小的内存,返回执行内存的指针。会对申请的内存初始化为0。两个参数: 元素个数和每个元素内存大小,
realloc:对原有内存地址进行扩容,两个参数:原有地址指针,本次需要申请的内存,返回重新分配内存的地址,底层是;如果原来地址后面有足够的空间,直接扩展,么有的话就重新分配一个更长的空间,把原来的内容拷过去,然后把原来的地址空间释放。原来地址为NULL则功能和上面的一致。

上面三个函数如果执行失败都会返回NULL,执行成功都会返回地址的指针,上面三个函数都需要stdlib.h头文件

5、函数调用传参,普通局部变量只能往调用内函数使用,外层函数不能使用,因为函数结束就释放了,但是堆区变量和全局变量哪里都可以使用。
6、经典操作系统中,栈的栈顶地址小,栈底地址大,压栈导致栈顶地址越来越小,出栈导致栈顶地址越来越大。

7、指针变量没有初始化和指针释放后没有置空都会导致野指针,也就是指向的地址可能有其他数据,还有返回函数局部变量的指针也会导致野指针。

8、指针是有步长的,当指针加一的时候指针移动步长,以前说过指针数组和数组的指针就是这个原理导致的

9、间接赋值,用函数形参:n级指针去修改n-1级指针实参的值

10、易错点:用指针变量++的方式读取和修改数组的元素的值,这个时候指针指向已经变了,如果free不会吧前面的元素free掉,这里要注意的。返回函数局部变量的指针会导致野指针。同一块内存不能释放两次,也就是释放一次后变成野指针了,野指针不能释放。

11、free做的工作:把申请的内存归还给系统,其他程序可以继续在这里分配内存了,但是并没有给指针变量置空,且内存内容是否清空需要看编译器,不同编译器实现不同的, 所以释放后最好给指针置NULL。

12、正常情况下,变量标志的地址存放数据,
一级指针变量标记的地址存放的是数据是另外一个变量内存的地址,二级指针变量标记的地址存放的数据是一级指针变量标记的地址,就是间接的访问

13、数组型的字符串,结尾是字符'\0'或者数字0,并不是字符'0',这点要注意。
sizeof数组型字符串长度包括结尾的'\0',但是string.h中strlen长度不包括'\0',这点要注意,以上长度特性无论数组字符串右边是数组{}形式还是字符串形式""形式的的,就算是""字符串形式的,编译器也会编译成数组形式的并加上'\0'字符。

如果初始化的字符串数组中间有'\0'字符(不是转义字符),后面还有其他字符,尽管当字符串的时候编译会只截取前面的部分,但是sizeof还是整个数组的长度包括最后面的'\0',strlen还是只会算前面部分的字符串的长度。如果是转义字符的话,把转义字符当做一个字符就行比如'\012'就是一个字符,不是'\0'这个字符。

14、指针做函数参数的输入输出特性:
输入特性:给主调函数指针分配内存后传给函数,在函数中处理指针内容。可以直接传变量的地址给函数的一级指针形参。也可以把二级指针传给函数二级指针形参。指针数组的指针可以传给函数二级指针形参。 输入特性指的是:函数可以使用指针来访问调用函数时传递给函数的数据。

输出特性;在主调函数声明指针,然后传给函数,在函数内部给指针分配内存。需要传指针的地址,也就是主调函数声明一个指针,然后把指针的地址传给函数的二级指针形参。然后才操作。
输出特性指的是:函数可以使用指针来修改调用函数时传递给函数的数据。