day11:
一:字符串的存储。
1:定义字符串的两种方式:①使用字符数组:char name[]="xhh";②使用指针来定义字符串:char *name2="nc";
2:系统中的内存分区:从高地址到低地址,栈:存放局部变量的,内存由系统进行管理。堆:存放对象,它由程序猿自己申请自己释放,它的内存需要程序猿自己管理。 全局区(又称静态区):存放全局变量与静态变量,它由系统管理。 常量区:存放常量,由系统管理,它是只读区。 代码区:存放代码,内存由系统管理,只读区。
总结:字符数组存储的字符串在栈中 ,栈是可读可写的,所以字符串的内容可任意修改,使用char 类型的指针定义的字符串是在常量区的,常量区是只读区,所以它所指向的内容是不可以修改的。
3:字符数组与字符指针的区别:
字符数组:char name []="xhh"; 相当于==>char name[]={'x','h','h','\0'}; 使用场景:当定义的字符串中的内容在后面需要修改时,就使用字符数组。
字符指针使用场景:当定义的字符串不需要修改时,就使用字符指针来定义字符串。
二:const关键字:
1 const修饰普通变量表示变量是只读的。不可修改的 。const的位置与其类型的位置可调换。
2 const修饰数组时表示数组是只读的 ,定义时必须进行初始化。变量也同样。
3 const修饰指针:①int const *p=# const放在*前面,表示指针指向的内容是只读的,不可以通过指针来操作指针所指向的内容。
②int *const p=# const放在*的后面,表示指针本身是只读的,不能改变指针所指向的内容。
4 const可以修饰形参:修饰形参时,可以保证这个形参不会被函数修改,同时也可以告诉函数调用者,本函数不会修改形参里面的内容,可以提高函数的可读性。 argc:说明档程序启动时,从控制台传入的参数的个数。 argv 从控制台传入的参数的值。
5 const修饰返回值,说明它的返回值不能修改。
三:字符串的练习:
四:动态存储空间的使用:
堆:===》是动态存储区。它由程序猿管理。
使用动态存储区:1:导入stdlib.h函数。malloc()向操作系统中申请堆中的一块存储空间。如果操作系统分配成功,会返回这个存储空间的地址,否则则返回NULL。 =====> int *p=malloc(size-t size);(向操作系统申请内存)=====> int *p=malloc(sizeof(int)); if(p!=NULL){ *p=20; printf("%d",*p); }=====> 输出20.
2:函数free(void *):告知操作系统此存储空间不再使用了。 (free(p);)
①有一个malloc,就必须有一个free函数与之对应,否则造成内存泄漏。
②若使用malloc,并通过free函数已经释放内存,再次释放,会造成程序崩溃。释放过的指针不可以再次释放,否则程序崩溃。
③防止再次释放造成程序崩溃,需在释放后清空指针。====>p=NULL; (清空后的指针再使用free无效果。free对空指针无效。)
五:指针函数:返回值为指针的函数。
注意:::局部变量的地址不可以作为函数的返回值,因为局部变量在函数结束时就已经释放,被系统回收。
六:函数指针:指向函数的指针就是函数指针。
1 函数指针定义格式:指针所指向的函数的返回值类型 (* 函数指针名称)(形参列表)===>例: void (*method)(); method=test;(一定无括号)
2 写一个函数指针:1:拷贝所要指向的函数, 2:把函数名称用小括号()括起来。 3:在函数名称前加*符号。 4:修改函数名称为指针名称。
若:①method(); //第一种调用方式。 ②(* method)(); //第二种调用方式。
3 若有参数,有返回值的函数:
定义其函数指针:
若函数:int minus(int num1,int num2)... 则可:pointer=minus; rs=pointer(10,20); printf("%d",rs); ===>输出rs=-10。
注意:函数指针的指向可改变,但必须指向同类型的函数。返回值类型与形参列表都相同的函数。
七:字符串练习。 (实现字符函数。)
1:字符串拷贝函数。
2:字符串拼接函数: