1.函数
(三要素:参数、功能、返回值)
(1)函数的调用
1.没有返回值:直接调用:函数名(实参);
2.有返回值:需要接收返回值,则需定义一个相同类型变量接收;
不需要,则可以直接调用函数。
如:
#include<stdio.h>
#include<string.h>
void fun(void)
{
print("is a function\n");
}
//求两数之和
void add(int n, int m) //形参
{
printf("%d\n", n+m);
}
//求两数之和
int add2(int n, int m)
{
return n+m;
}
int sub(int n, int m);
int main(int argc, char const *argv[])
{
int a=4, b=5;
//调用
fun();
add(2,3);
int num=add2(a, b);
printf("num=%d\n", num);
int ret=sub(1, 2);
printf("ret=%d\n", ret);
return 0;
}
int sub(int n, int m)
{
printf("在主函数下边\n");
int num=n+m;
return num;
}
(2)函数传参
①值传递
单向传递,将实参传递给形参之后,改变形参,实参不受影响。
如:
②地址传递
双向传递,函数数中修改形参,实参会随之变化 (通过地址间接修改内容)
③ 数组传递:
和地址传递一样,虽然参数当中存在数组的定义,但是会认为是一个指针
(3)动态内存开辟(开辟堆区空间)
动态内存开辟存在的原因:
<1>在技术方面,普通的空间申请,都是在全局或者栈区,全局一般不太建议大量使用,而栈空间有限,那么如果一个应 用需要大量的内存空间的时候,需要通过申请堆空间来支持基本业务。
<2>在应用方面,程序员很难一次预估好自己总共需要花费多大的空间。想想之前我们定义的所有数组,因为其语法约束,我们必须得明确"指出"空间大小.但是如果用动态内存申请(malloc)因为malloc是函数,而函数就可以传参,也就意味着,我们可以通过具体的情况,对需要的内存大小进行动态计算,进而在传参申请,提供了很大的灵活性
①开辟空间
#include <stdlib.h>
void *malloc(size_t size);
功能:在堆区开辟空间
参数:size:开辟空间的大小(单位:字节)
返回值:
成功:返回开辟空间的首地址
失败:NULL
②释放空间
#include <stdlib.h>
void free(void *ptr);
功能:释放堆区空间
参数:ptr:堆区空间的首地址
返回值:无
int *p = malloc(size);
free(p);
// 对p进行释放的时候需要对p赋值一个NULL,避免成为野指针
p = NULL;
注意:
1.手动开辟堆区空间,要注意内存泄漏
当指针指向开辟堆区空间后,又对指针重新赋值,则没有指针指向开辟堆区空间,就会造成内存泄漏
2.使用完堆区空间后,及时释放空间 free
③常见的动态内存错误
<1>对空指针的应用操作
<2>对动态开辟空间的越界访问
<3>对非动态开辟内存使用free释放
<4>使用free释放动态内存的一部分
<5>对同一动态内存多次释放
<6>动态开辟内存忘记释放(内存泄露)
在子函数中开辟堆区空间,想在主函数中拿到堆区空间首地址有两种方法:
1.传参方式
2.返回值方式
2.string函数族
(1)strcpy
#include <string.h>
char *strcpy(char *dest, const char *src);
功能:实现字符串的复制
参数:dest:目标字符串首地址
src:源字符串首地址
返回值:目标字符串首地址
复制包括 '\0'
解析:
相当于把字符串a的数据复制到s内
包括'\0'的复制,然后复制到a的'\0',然后赋值结束。
s[5]='\0',后边继续延续s本来的数据输出
char *strncpy(char *dest, const char *src, size_t n);
功能:实现字符串的复制
参数:dest:目标字符串首地址
src:源字符串首地址
n:要复制的字符个数
返回值:目标字符串首地址
解析:
同上解析,
唯一区别就是s只复制a的前两个数据,后边的按原数据输出
(2)strlen
#include <string.h>
size_t strlen(const char *s);
功能:计算字符串的实际长度
参数:s:字符串的首地址
返回值:实际长度
(3)strcat
#include <string.h>
char *strcat(char *dest, const char *src);
功能:字符串拼接
参数:dest:目标字符串首地址
src:源字符串首地址
返回值:目标字符串首地址
解析:
s空间足够大,就会在s原数据后拼接a的全部数据
s空间能存多大,拼接后的存储数据空间就只能多大,多的丢掉
char *strncat(char *dest, const char *src, size_t n); 将src的前n个字符拼接到dest中
(4)strcmp
#include <string.h>
int strcmp(const char *s1, const char *s2);
功能:用于字符串比较
参数:s1, s2用于比较的字符串首地址
返回值:
从字符串首个字符开始比较字符的 ASCII的大小,如果相等继续向后比较
s1 > s2 正数 1
s1 == s2 0
s1 < s2 负数 -1