1、函数语言,利用函数设计成一个个·模块,这些模块进行组合(顺序分支循环)
设计模块:A、调用者 上级 B被调用者 下级
A申请一段空间 如何处理 把空间交给B
B拿到这个空间 处理 返回给A(把空间的首地址传给A,直接把空间)
实参形参储存位置不同,不同函数有不同的栈区;
通过下级函数修改上级函数中的地址的值;
*a =200//下级函数a中存的是上级函数中a的地址,而*a直接通过该地址访问到了上级的a,通过赋值改变上级函数中a的值;*的意思是访问a里面的地址;没有*直接p=xxx;只是修改了该函数中p里面存的a的地址,上级函数a不会改变;
二维指针反向更新上级地址;
查错:
p是局部变量,第三行用malloc申请的堆空间的值为局部变量赋值,函数返回后局部变量消失,而堆空间未消失,没有回收导致了内存泄漏;
第七行str未更新没有传地址,strcpy向空地址赋值导致段错误;
第九行可能打印出不是hello world的信息,常量字符串 赋值给局部变量数组,函数返回局部变量消失,常量字符串依然存在,用等号给空地址赋值,虽然该地址可以赋值给str,但是该地址已经随着函数返回而成为随机地址,里面存的值已经不确定了;如果返回值是地址就应该返回静态区或者堆区;
正确;
*p指向的是内容,可能是非法内容;要交换两个指针指向的值,假设p1
存的整数直接int一个变量;交换内容
值不交换,交换p1,p2里的地址;
---------------------------------------------------------------------------------------
字符串
*p该指针变量存的是常量字符串的首地址,所以输出为L;
p里存的是地址,*p是访问地址里的值;
形参中sizeof(str) = 4 || 8;根据系统位数,指针大小;只有确定了数组名初始化后才有大小;
写一个标准宏MIN,这个宏输入两个参数并返回较小的一个;
(1)输入参数的逻辑含义:上层空间交给子函数来处理,描述这个空间,设计子函数的时候,该怎么写形参,
基本数据类型空间(看)
double a;
int fun (double data){};
struct abc a1;
int fun(struct abc a1){}//结构体支持拷贝操作,主函数和子函数有2个一模一样的结构体(空间浪费,工程中不这样子,靠传地址解决);
int fun (const struct abc *data){
data ->id = xxx;//有const 只是查看该结构体,没有就修改空间;
}//结构体的空间处理,不考虑拷贝,都是指针来指向;
字符空间 看
int fun (const char *);
因为函数声明中有参数有不同的数据类型,为了避免参数不匹配c提出void *;
void *:形参中出现,指任意空间地址;后面一定要有个数限制;size_t ssize_t;
time_t now;
time(&now);//利用传递参数修改上层空间值,
now = time(NULL);//传递参数为空时,利用返回值修改上层空间now值
------------------------------------
总结:
设计函数,输入参数,返回值
子函数
操作空间的类型 判断这个空间的结束标志是否确定
int fun(const char *data)//判断字符空间空格个数;
读空间
写空间
1、int fun(int a);
2、void fun (const void *data,size_t len,int *res)//通过参数来统计不用返回值,需要上层空间给一个地址;//用地址指向任意空间,长度
int fun (const void *data,size_t len)
1、int fun(const char *data,char flags);//指定字符
2、int fun (char *data,char flags);
数据压缩编码;有损或无损编码;
根据数据输入来决定输出;
void *runCode(const void *raw_data,int *len)//输入一个空间,大小
//输出一个编码后的空间首地址(返回值更新),这个空间的数量(参数更新);
int main() {
char *data = ......;
int len = 10;
char *result;
result = runCode(data,&len);}
--------------------------------------------------------
int *runCode(const void *raw_data,int len,void **result);
遍历,内存管理;
越界一般就是段错误;