目录
1:使用assert
当需要判断的时候就可以用assert
为假的时候会返回一个错误
看下面的代码
#include<stdio.h>
#include<assert.h>
int my_strlen(const char* p) {
int count = 0;
assert(p != NULL);
while (*p++ != '\0') {
count++;
}
return count;
}
int main() {
char arr[] = "abcdefghijklmnopqrstuvwxyz";
int ret=my_strlen(arr);
printf("%d", ret);
}
这里的返回类型可以使unsigned int =size_t,这样返回值的范围会扩大一倍
#include<stdio.h>
#include<string.h>
int main() {
if (strlen("abc") - strlen("abcdeft") > 0) {
//strlen函数的返回值是size_t
// -3的原反补
//10000000000000000000000000000101
//11111111111111111111111111111010
//11111111111111111111111111111101
printf("hehe\n");
}
else {
printf("haha\n");
}
}
#include<stdio.h>
#include<assert.h>
void my_strcpy(char* des, char* sor) {
/*if (des == NULL || sor == NULL) {
return;
}*/
assert(des != NULL);//断言,release版本可以优化掉
assert(sor != NULL);
while (*des++ = *sor++) {
;
}
}
int main() {
char arr[] = "abcdef";
char arr2[10];
my_strcpy(arr2, arr);
my_strcpy(arr2, NULL);
printf("%s", arr2);
}
用assert断言(头文件为assert.h)des和sor两个指针不是空,如果是空指针,证明断言为假,就会出现这种情况
2:尽量使用const
const修饰指针的时候,如果放在*的左边,代表所指向的指针所指向对象的内容无法被改变,如果修饰数组指针,那么可以防止数组里面的元素被意外的修改
如果放在*的右边,代表所指向的对象无法被改变
看下面的代码
#include<stdio.h>
int main() {
//const修饰指针
//const放在*的左边,限制的是*p,也就是指针所指向的对象的内容
//int const*p和const int* p是一样的
int a = 20;
int b = 10;
const int* p = &a;
*p = 10;//错误的
p = &b;
int const* pb = &b;
*pb = 20;//错误的
pb = &a;
//const放在*的右边,限制的是p,也就是指针所指向的对象
int c = 30;
int d = 40;
int* const pc = &c;
pc = &d;//错误的
*pc = 40;
}
3:养成良好的编程风格
下面代码函数的内容有六种写法
int main() {
char arr[] = "abcdef";
char arr2[10];
/*char arr6[] = "abcdefghijklmn";
char arr7[4];*///目的地字符串的空间必须要足够
//char arr5[] = { 'a','b','c' };//源头字符串必须要有\0
/*char arr3[] = "ghijk";
const char* arr4 = "#########";//常量字符串是放在常量区的,是不能修改的
char* ret = my_strcpy(arr4, arr3);*/
char*ret=my_strcpy(arr2, arr);
printf("%s", ret);
}
第一种最简单
第二种将用后置++使代码简洁
第三种通过while()循环自身就带的判断来判断是否遇到\0
第四种使用assert来断言,使当传进来的指针使空指针的时候会报错
第五种使用const修饰指针,防止指针所指向的数组的元素被意外修改,也就是防止传反数组地址
第六种在上面,返回类型为char*,返回一个指针,但是最后des所指向的内容不是其实地址,所以要将他的其实地址存起来
#include<stdio.h>
//版本一
void my_strcpy(char* des, char* sor) {
while (*sor != '\0') {
*des = *sor;
des++;
sor++;
}
*des = *sor;
}
//版本二
void my_strcpy(char* des, char* sor) {
while (*sor != '\0') {
*des++ = *sor++;
}
*des = *sor;
}
//版本三
void my_strcpy(char* des, char* sor) {
//1:复制字符
//2:遇到\0停止
while (*des++ = *sor++) {
;//空语句
}
}
//版本四
#include<assert.h>
void my_strcpy(char* des, char* sor) {
/*if (des == NULL || sor == NULL) {
return;
}*/
assert(des != NULL);//断言,release版本可以优化掉
assert(sor != NULL);
while (*des++ = *sor++) {
;
}
}
//版本五
void my_strlen(char* des, const char* sor) {
//const防止原字符数组被意外修改,也防止将目的地的字符复制到源头的字符数组中
assert(des != NULL);
assert(sor != NULL);
while (*des++ = *sor) {
;
}
}
int main() {
char arr[] = "abcdef";
char arr2[10];
my_strcpy(arr2, arr);
my_strcpy(arr2, NULL);
printf("%s", arr2);
}
4:添加必要的注释
上面的代码都有注释
5:避免编程陷阱
看积累了