C提高day03---05---项目开发代码书写手法
练习题目:
键值对(”key = valude”)字符串,在开发中经常使用;
要求1:请自己定义一个接口,实现根据key获取valude;40分
要求2:编写测试用例。30分
要求3:键值对中间可能有n多空格,请去除空格。30分
注意:键值对字符串格式可能如下:
"key1 = valude1" "key2 = valude2 " "key3 = valude3" "key4 = valude4" "key5 = " "key6 =" "key7 = " |
int getKeyByValude(char *keyvaluebuf, char *keybuf, char *valuebuf, int * valuebuflen); |
int main() { getKeyByValude(“key1 = valude1”, ” key1”, buf, &len); |
源代码如下:
//去除字符串中的前后的空格! int trimSpace(char* str, char* newstr) { char* p = str; int i = 0; int j = 0; int n_length = 0; if (str == NULL || newstr == NULL) { printf("Error: pointer is NULL!\n"); return -1; }
i = 0; j = strlen(p) - 1; while (isspace(p[i]) && p[i] != '\0') { i++; } while (isspace(p[j]) && p[j] != '\0') { j--; } n_length = j - i + 1; strncpy(newstr, str + i, n_length); newstr[n_length] = '\0'; return 0; } |
int getKeyByValude(char* keyvaluebuf, char* keybuf, char* valuebuf) { int ret = 0; if (keyvaluebuf==NULL || keybuf==NULL || valuebuf==NULL) { return -1; } //1. 首先查找子串keybuf有没有在母串keyvaluebuf里面! char* p = NULL; p = keyvaluebuf; p = strstr(p, keybuf); if (p==NULL) { ret = -1; return ret; } //注意:要让辅助指针p重新初始化 p = p + strlen(keybuf); //2. 然后检查有没有等于号! p = strstr(p, "="); if (p == NULL) { ret = -1; return ret; } //注意:要让辅助指针p重新初始化 p = p + strlen("="); //3. 在=后面去除空格! ret=trimSpace(p,valuebuf); if (ret!=0) { printf("func trimSpace() error : %d\n",ret); return ret; } return 0; } |
int ret = 0; char* key_value = " key2 = valude2 "; char* key2 = "key2"; char buf[1024] = { 0 }; int buf_len = 0;
ret=getKeyByValude(key_value, key2,buf); if (ret!=0) { printf("func getKeyByValude() error : %d\n ",ret); return ret; } printf("sub str is: %s\n",buf); |
C提高day03--06--一级指针易错的模型分析(这是重难点)
函数定义时有三个形式参数;调用此函数时却给了它四个参数,编译通过了!这是C语言上的灰色地带,以后会在《C++语言对C语言的扩展》中讲到!
第一种错误:char *字符串作为函数的参数,容易出错!
char *p=NULL; char buf[1024]={0}; strcpy(p,buf); //error |
你必须分配好内存空间,才能调用strcpy函数!出错的原因就是没有分配好内存空间! |
或者这种错误:
void copy_str(char * from,char *to){ if(*from=='\0' || *to=='\0'){ ... } //error! } |
出错了!*from表示指针from所指向的内存空间里边的数据。它完全可以是'\0' |
此处最好创建两个辅助指针,去分别承接from与to指针! |
正确的应该是:if(from==NULL || to==NULL) { ....... } |
注意:
写法::char *p={0}; 完全等价于 char *p=NULL; |
C语言里边所有的你都知道,但是你不一定会调用!
Java语言所有的内容你都会调用,但是不一定你都知道!
第二种错误:字符数组越界(语法级别的越界)
char p[3]="abc"; //错误:字符的数组最后边默认还有一个'\0'呢!数组下标越界! |
第三种情况:不断修改指针变量的值,也容易出错!
char *p=NULL; p=(char *)malloc(50*sizeof(char)); |
free(p); //释放指针p所指向的内存空间! p=NULL; //然后把指针p赋值为NULL; |
注意:指针p是一个常量指针,p++; p--;什么的都是错误的! |
第四种:你要向外部传递什么?
函数内部的局部变量,传递不到外部!因为函数内部的变量,全部在临时内存空间,一旦调用结束,就会被释放!
C提高day03---07---C语言中const知识点总结
const关键字在C语言中的表现与在C++语言中的表现,有不同之处!
C语言中,const用来把一个变量声明为“只读”!
const int a; 与 int const a; 这两种写法是一样的!代表整形变量a的值不能被修改! |
const char * c; //c是一个指向char的指针,const修饰的是内存空间里的数据,指针本身可以被修改! |
char * const d; //const修饰的是指针d!内存空间里的数据可以被修改!指针本身的指向不可以被修改! |
const char * const e; //二者都不能被修改! |
结论:指针变量本身与指针所指向的内存空间的数据,是两个完全不同的概念!
帮助记忆的方法:就看*与const这两个东西,哪一个与指针变量的名字挨得近!
- const char * c; 已知c是一个指针,此处星号与变量名紧紧挨着,*c就代表内存空间里的数据,const 数据; 数据就不能被修改!指针本身c可以被修改!
- char * const d; 已知d就是一个指针!此处const与d挨得最近,所以指针变量本身不能被修改!内存空间里边的数据可以被修改!
const的好处:
- 在指针作为函数参数的时候,可以有效地提高代码可读性,减少bug!
- 可以清楚的分清楚:指针作为函数参数时的,输入特性或者输出特性!
一个C语言源文件里:const int a=100;
在另一个C语言源文件如何使用a呢? extern const int a; //此处a不能再赋值啦!
const int b=200; // b=300; 当然错误! int *p=&b; *p=500; printf("b = %d\n",b); // b = 500 |
所以C语言中的const是一个冒牌货!我们还可以通过指针来修改它! |
C++语言中的const与在C语言中的const,有很大不同!以后再讲!
void getMem1201(const char* p) { p = 1; //OK p = 2; //OK // p[1]='a'; error! // const char* p; 数据不可被修改!指针本身可以被修改! } |
void getMem1202(char* const p) { // char* const p; 指针本身不可被修改! 数据可以被修改! } |
void getMem1203(const char* const p) { //二者都不能被修改啦! //是只读的! } |
char* p1 = NULL; const char* p2 = NULL; //p2是一个指针,*号与p2挨得最近,*p2表示的是内存空间里边的数据; //所以const修饰的是数据,数据不可变!指针本身是可以变的! p2 = 1; //OK getMem1201(p2); //OK |