实现strlen
strlen在文档中的形式是这样定义的,size_t strlen(const char* string);
返回类型是size_t的一个类型,c语言中定义size_t为typedef unsigned int size_t;,返回一个无符号整型。
strlen的参数为一个字符型指针,即要计算长度的字符串的首地址,使用const修饰是为了防止字符串里面的内容被函数修改。
strlen()计算的是字符串的长度,当遇到'\0'时认为字符串已经结束,并且不会将'\0'计入到字符串长度中。
#include<stdio.h>
#include<assert.h>
#include<string.h>
size_t my_strlen(const char* str)
{
assert(str); //判断传过来的指针是否为NULL,如果为NULL,则进行断言,报出错误。
int count = 0;
while (*str != '\0') //如果指针没有指向字符串的最后,就继续执行
{
count++;
str++; //指针向前走一个字节
}
return count;
}
int main()
{
char arr[] = "abc\0def";
int res = my_strlen(arr);
printf("%d\n", res);
printf("%d\n", strlen(arr)); //遇到'\0'就会停止计算长度
return 0;
}
//strlen
size_t my_strlen(const char* str)
{
const char* start = str;
while (*str++); //将str指向
return (str - start - 1); // a b c d e f /0 ? 此时str指向的是?的地址,即不知道该元素为多少,
// str - start 为 ? 到 a 之间有多少字符元素,即为 7 个,(因为包含了 \0 )所以要减去1
}
int main()
{
char arr[] = "abcdef";
int res = my_strlen(arr);
printf("%d", res);
return 0;
}
实现strcpy
strcpy()函数在文档中的定义为 char* strcpy(char* strDestination, const char* strSource);
第一个形参为char*类型的指针,代表目标字符串的首地址。
第二个形参为char*类型的指针,代表源字符串的首地址。
函数返回的值为char*类型的指针,即返回的是已经拷贝完的字符串的首地址。
strcpy()函数就是将字符串strSource拷贝到strDestination字符串中,并且会将strSource字符串最后的'\0'也拷贝进去,如果strDestination字符串原来不为空,则会覆盖原来的内容。
//strcpy
#include<stdio.h>
#include<assert.h>
//my_strcpy函数设计返回值类型是为了实现函数的链式访问
char* my_strcpy(char* dest, const char* str)
{
assert(dest && str);
char* start = dest; //保存目标字符串的首地址,以便函数返回
//while (*str != '\0')
//{
// *dest = *str;
// str++;
// dest++;
//}
//*dest = *str; //此时str指针指向的就是'\0',所以需要将'\0'也拷贝到目标字符串。
//上面的while可以缩短为
while (*dest++ = *str++); //即先执行*dest=*str,然后将*str的值交给while判断真假
//然后dest++和str++,如果将*str='\0'的值赋给*dest后,while判断'\0'为0,为假,则不进入循环
//此时刚好已经将'\0'字符拷贝给目标字符串。
return start; //返回目标字符串的首地址。
}
int main()
{
char arr1[] = "abcdef";
char arr2[20] = "xxxxxxxxxxxx";
my_strcpy(arr2, arr1); //将arr1字符串里面的内容拷贝到arr2中。
printf("%s\n", arr2);
printf("%s\n", my_strcpy(arr2, arr1)); //函数的链式访问
return 0;
}
const关键字
const放在*左边时,修饰的是*p,所以*p的值不能改变,但是p的值可以变。
const放在*右边时,修饰的是p,所以p的值不能改变,但是*p可以变。
即左定值,右定向。
//const关键字
#include<stdio.h>
int main()
{
const int num = 10;
//num = 20; //当变量使用const修饰后,则变量的值就不可以改变了。
const int* pa = #
//const可以修饰指针
//const放在*左边 (const int* p 或者 int const * p)
//代表const修饰的是*p,表示p指向的对象不能通过p来改变,但是p变量中的地址是可以改变的。
//即*p的值不能改变,p的值可以改变。
int n = 10;
const int* pb = #
//*pb = 40; //不被允许
pb = &n; //可以改变
//const放在*右边(int* const p)
//const修饰的是p,表示p的内容不可以被改变,但是p指向的对象是可以通过p来改变的
//即p的值不可以改变,但是*p的值可以变
int* const pc = &n;
int m = 10;
//pc = &m; //不被允许
*pc = 50; //可以改变
printf("%d\n", n);
return 0;
}
面试题分析
//面试题分析
#include<stdio.h>
int main()
{
int i = 0;
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
for (i = 0; i <= 12; i++)
{
arr[i] = 0;
printf("hh\n");
}
return 0;
}
实现字符串和单词逆置
将 i like beijing. 逆置为 beijing. like i
//逆序字符串中的单词
// i like beijing. --> beijing. like i
#include<stdio.h>
#include<string.h>
void my_reverse(char* left, char* right)
{
while (left < right)
{
char temp = *left;
*left = *right;
*right = temp;
left++;
right--;
}
}
int main()
{
char arr[] = "i like beijing.";
int len = strlen(arr);
my_reverse(arr, arr + len - 1);
char* str = arr;
while (*str != '\0')
{
char* start = str;
while (*str != ' ' && *str != '\0')
{
str++;
}
my_reverse(start, str - 1);
if (*str != '\0')
{
str++;
}
}
printf("%s\n", arr);
return 0;
}