Q1:请编写能直接实现strlen()函数功能的代码
首先翻阅官方strlen文档
function
<cstring>
strlen
size_t strlen ( const char * str );
Get string length
Returns the length of the C string str.
The length of a C string is determined by the terminating null-character: A C string is as long as the number of characters between the beginning of the string and the terminating null character (without including the terminating null character itself).
This should not be confused with the size of the array that holds the string. For example:char mystr[100]="test string";
defines an array of characters with a size of 100 chars, but the C string with which mystr has been initialized has a length of only 11 characters. Therefore, while sizeof(mystr) evaluates to 100, strlen(mystr) returns 11.
In C++, char_traits::length implements the same behavior.
可以看到strlen函数返回字符串的长度,字符串的长度取决于null-character,也是就'\0';那么我们开始写代码;
#include <iostream>
#include <stdio.h>
int strlen_m(const char *str)
{
int i = 1;
for (i = 0; str[i] != '\0'; ++i);
return i;
}
int main()
{
//char c[5] = { 'A','B','q','\0','c' };
char c[5] = { 'A','B','q','6','c' };
const char *mess = "aaws";
printf("c_strlen:%d\n", strlen(c));
printf("c_strlen_m:%d\n", strlen_m(c));
printf("mess_strlen:%d\n", strlen(mess));
printf("mess_strlen_m:%d\n", strlen_m(mess));
return 0;
}
输出:
c_strlen:19
c_strlen_m:19
mess_strlen:4
mess_strlen_m:4
A:strlen的实质就是寻找'\0'符号,返回对应的下标。这里我做了一个小测试,定义字符数组长度为5,然后用strlen函数测试长度,结果为19,可以看到这并不正确,这是因为我末尾没有给他添加'\0'字符的原因。
那字符串是怎么用strlen返回长度的呢?于是我又定义了一个const char*mess = "aaws";可以看到strlen(mess)的结果为4,看来函数可以解决返回字符串长度问题,创建常量字符串的时候,会在末尾自动添加一个'\0';
Q:请编写能直接实现strstr()函数功能的代码
function
<cstring>
strstr
const char * strstr ( const char * str1, const char * str2 );
char * strstr ( char * str1, const char * str2 );
Locate substring
Returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of str1.
The matching process does not include the terminating null-characters, but it stops there.
Parameters
str1
C string to be scanned.
str2
C string containing the sequence of characters to match.
Return Value
A pointer to the first occurrence in str1 of the entire sequence of characters specified in str2, or a null pointer if the sequence is not present in str1.
#include <iostream>
#include <stdio.h>
char* strstr_m(char* str, const char* sub)
{
char* p;
const char* q;
for (int i = 0; i < strlen(str); ++i)
{
p = &str[i];
q = sub;
if (*p == *q)
{
for (int j = 0; j < strlen(sub); ++j)
{
p++;
q++;
if (*q == '\0')
return&str[i];
}
}
}
return NULL;
}
int main()
{
char mess[] = "hello world";
const char* inner = "ld";
printf("strstr:%s\n", strstr(mess, inner));
printf("strstr_m:%s\n", strstr_m(mess, inner));
return 0;
}
//输出
strstr:ld
strstr_m:ld
A:strstr返回字符串中存在子字符串的头指针,如果不存在则返回NULL;我之前看到一篇博文实现strstr是错误的。于是我在这里重新实现一次。
Q:const char * const p是什么意思?
A:const char *const p;//内容和地址都不可以改变
const char *p; 地址无法改变,值可以修改
有篇博客说char const *p值不可以修改,但是我测试出来是可以修改的,欢迎斧正。
而且我vs2019 也无法定义 char* const p;
Q:memset、memcpy和strcpy的根本区别
A:
memset:
void * memset ( void * ptr, int value, size_t num );
ptr
Pointer to the block of memory to fill.
value
Value to be set. The value is passed as an int, but the function fills the block of memory using the unsigned char conversion of this value.
num
Number of bytes to be set to the value.
size_t is an unsigned integral type.
menset将从ptr指针开始 num个长度的地址初始化为 values值。
#include <iostream>
#include <stdio.h>
int main()
{
char p[] = "44458";
memset(p, 'q', 3);
printf("%s\n",p);
}
//输出
qqq58
memcpy
void * memcpy ( void * destination, const void * source, size_t num );
destination
Pointer to the destination array where the content is to be copied, type-casted to a pointer of type void*.
source
Pointer to the source of data to be copied, type-casted to a pointer of type const void*.
num
Number of bytes to copy.
size_t is an unsigned integral type.
从指针source指向地址开始复制num个值到destination中。返回destination头指针
因为拷贝的内存地址连续,所以并行计算每次从source取出多个值并复制给destination,比我们单个单个赋值会快很多。
strcpy:
char * strcpy ( char * destination, const char * source );
destination
Pointer to the destination array where the content is to be copied.
source
C string to be copied.
warning:To avoid overflows, the size of the array pointed by destination shall be long enough to contain the same C string as source (including the terminating null character), and should not overlap in memory with source.
warning:此处为了避免溢出,所以destination array必须要保证有足够的size来存放source中的字符串。
此函数只能拷贝字符串,它将source中的字符串全拷贝到destination中。这就导致了我们必须保证destination内存足够存放source。会引发一系列安全问题,在vs2019编辑器会提示你C4496错误,意思是strcp函数不安全,建议你使用安全的strcp_s函数,我在这里不继续讨论他的安全安全性,如果你感兴趣你可以跳转至链接(https://blog.csdn.net/leowinbow/article/details/82380252)。
这时候你在include文件前面加上一行#define _CRT_SECURE_NO_WARNINGS就可以暂时让编辑器忽略这个问题继续运行。
而且我发现一个很有趣的问题,直接上代码:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <stdio.h>
#include <cstringt.h>
int main()
{
const char y[] = "585";
char *p;
p = (char*)calloc(5,sizeof(char));
memset(p, '1', 5);
printf("1:%s\n", p);
strcpy(p, y);
printf("2:%s\n", p);
printf("3:%d\n", p[3]);
printf("4:%d\n", p[4]);
return 0;
}
//输出
1:11111
2:585
3:0
4:49
此处我给destination也就是p 申请了5个字节内存,然后将他们全部初始化置为1。然后运行strcpy函数将y拷贝到p中。
y占3个字节,拷贝后打印p会发现,strcpy操作除了将y中内容复制到p外,还在末尾p[3]处添加了一个'\0'字符,而p[4]则没有变化,还是我menset置1的值。(1的ASCII码为49)。
参考链接:https://blog.csdn.net/qq_42637045/article/details/102644120;
、、