常见的coding技巧:
模拟实现库函数:strcpy
我们先来看一下strcpy是如何使用的:
#include
#include
int main()
{
char arr1[] = "hello bit";
char arr2[20] = "xxxxxxxxxxxxx";
//strcpy(arr2, arr1);
//printf("%s\n", arr2);
printf("%s\n", strcpy(arr2, arr1));
return 0;
}
接下来我们来实现它:
#include
void my_strcpy(char* dest, char* src)
{
while (*src != '\0')
{
*dest = *src;
dest++;
src++;
}
*dest = *src;// \0 的拷贝
}
int main()
{
char arr1[] = "hello bit";
char arr2[20] = "xxxxxxxxxxxxx";
my_strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
我们还可以使用assert对它进行优化:
#include
#include
void my_strcpy(char* dest, char* src)
{
//断言
assert(dest != NULL);
assert(src != NULL);
while (*src != '\0')
{
*dest = *src;
dest++;
src++;
}
*dest = *src;// \0 的拷贝
}
int main()
{
char arr1[] = "hello bit";
char arr2[20] = "xxxxxxxxxxxxx";
char* p = NULL;
//my_strcpy(p, arr1);
my_strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
通过assert,我们可以确保某些事情不会发生,一旦发生,它就会报错,这样就能方便我们快速找到错误。
我们还可以将字符和\0的拷贝放到一起:
#include
#include
void my_strcpy(char* dest, char* src)
{
//断言
assert(dest != NULL);
assert(src != NULL);
while (*dest = *src)//赋值表达式,比如把h赋给*dest,表达式的结果就是h的ASCII码值
{
dest++;
src++;
}
}
int main()
{
char arr1[] = "hello bit";
char arr2[20] = "xxxxxxxxxxxxx";
char* p = NULL;
//my_strcpy(p, arr1);
my_strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
还可以这样写:
#include
#include
void my_strcpy(char* dest, char* src)
{
//断言
assert(dest != NULL);
assert(src != NULL);
while (*dest++ = *src++)//赋值表达式,比如把h赋给*dest,表达式的结果就是h的ASCII码值
{
;//空语句
}
}
int main()
{
char arr1[] = "hello bit";
char arr2[20] = "xxxxxxxxxxxxx";
char* p = NULL;
//my_strcpy(p, arr1);
my_strcpy(arr2, arr1);
printf("%s\n", arr2);
return 0;
}
此外,我们还可以对返回类型进行优化:
#include
#include
//函数返回的是目标空间的起始地址
char* my_strcpy(char* dest, char* src)
{
char* ret = dest;
//断言
assert(dest != NULL);
assert(src != NULL);
while (*dest++ = *src++)// 赋值表达式,比如把h赋给*dest,表达式的结果就是h的ASCII码值
{
;//空语句
}
return ret;
}
int main()
{
char arr1[] = "hello bit";
char arr2[20] = "xxxxxxxxxxxxx";
char* p = NULL;
//my_strcpy(p, arr1);
//my_strcpy(arr2, arr1);
//printf("%s\n", arr2);
printf("%s\n", my_strcpy(arr2, arr1));
return 0;
}
另外,为了保证传进去的arr1不被修改,我们还可以加上const进行修饰:
#include
#include
//函数返回的是目标空间的起始地址
char* my_strcpy(char* dest, const char* src)
{
char* ret = dest;
//断言
assert(dest != NULL);
assert(src != NULL);
while (*dest++ = *src++)// 赋值表达式,比如把h赋给*dest,表达式的结果就是h的ASCII码值
{
;//空语句
}
return ret;
}
int main()
{
char arr1[] = "hello bit";
char arr2[20] = "xxxxxxxxxxxxx";
char* p = NULL;
//my_strcpy(p, arr1);
//my_strcpy(arr2, arr1);
//printf("%s\n", arr2);
printf("%s\n", my_strcpy(arr2, arr1));
return 0;
}
有以下两种方式可以修改num的值:
int main()
{
int num = 10;
num = 20;
int* p = #
*p = 200;
return 0;
}
现在我们加上const:
#include
int main()
{
const int n = 100;
//n = 200;//err
int* p = &n;
*p = 20;
printf("%d\n", n);
return 0;
}
加上const是为了不让n的值发生变化,但是现在我们却可以通过地址的方式来改变它,于是我们可以进行以下操作:
int main()
{
const int n = 100;
//n = 200;//err
//int* p = &n;
//*p = 20;
//printf("%d\n", n);
const int* p = &n;
//*p = 20;//err
return 0;
}
通过以上代码我们可以发现const是可以修饰指针的:
//const 修饰指针的时候
//当const 放在*的左边的时候,限制的是指针指向的内容,不能通过指针变量改变指针指向的内容,但是指针变量本身是可以改变的
//当const 放在*的右边的时候,限制的是指针变量本身,指针变量本身是不能改变的,但是指针指向的内容是可以通过指针来改变的
#include
int main()
{
int m = 10;
int n = 100;
//const可以修饰指针
const int* p = &m;
//*p = 0;//err
p = &n;//ok
printf("%d\n", m);
return 0;
}
#include
int main()
{
int m = 10;
int n = 100;
//const可以修饰指针
int* const p = &m;
*p = 0;//ok
//p = &n;//err
printf("%d\n", m);
return 0;
}
#include
int main()
{
int m = 10;
int n = 100;
//const可以修饰指针
const int* const p = &m;
//*p = 0;//err
//p = &n;//err
printf("%d\n", m);
return 0;
}
练习:
模拟实现一个strlen函数
//模拟实现一个strlen函数
//assert
//const
//size_t 是专门为sizeof设计的一个类型
//size_t --> unsigned int / unsigned long
//>=0
#include
#include
size_t my_strlen(const char* str)
{
assert(str != NULL);
size_t count = 0;
while (*str != '\0')
{
count++;
str++;
}
return count;
}
int main()
{
char arr[] = "abc";
size_t len = my_strlen(arr);
printf("%zd\n", len);//zd是专门用来打印size_t类型的值的
return 0;
}
//%u 无符号整数的
直接看错误提示信息(双击),解决问题,或者凭借经验就可以搞定,相对来说简单。
int main()
{
int a = 10//编译期间找到的一般都是语法问题
return 0;
}
看错误提示信息,主要在代码中找到错误信息中的标识符,然后定位问题所在,一般是标识符名不
存在或者拼写错误。
//链接型错误是在链接期间发现的错误
int Add(int x, int y)
{
return x + y;
}
int main()
{
int ret = add(2, 3);
return 0;
}
借助调试,逐步定位问题,最难搞。
#include
int Add(int x, int y)
{
return x - y;
}
int main()
{
int ret = Add(2, 3);
printf("%d\n", ret);
return 0;
}
实用调试技巧(1)