C++ <cstring>字符串库函数的自定义实现

简介: C++ <cstring>字符串库函数的自定义实现

字符串处理函数包括几大类可以满足对char*字符串大部分操作,需要包括头文件<cstring>或者<string.h>。我是更喜欢用string类操作字符串的,只是我家小朋友刚开始学指针,而字符串操作是非常适合练基本功的。所以选几种操作讲讲,看它们如果不用库函数是怎么实现的:


声明、串长、复制

#include <iostream>
#include <cstring>
#include <assert.h>
using namespace std;
int strLen(const char *s)
{
  if (NULL==s) throw "Invalid argument";
  //assert(s!=NULL); //或者用<assert.h>库函数assert() 
    int i=0;
    while(*s++!='\0') i++;  //两种循环都可以 
    //for(i=0;*s!='\0';++s) i++;
    return i;  
}  
//甚至可以不用中间变量来求字串长,网传是一道某大公司的面试题
//if (*s) return (1+strlen(s+1)); else return 0;
//或直接三目操作符:return (*s)?(1+strlen(s+1)):0;
//酱紫的递归计算巨长的字串来估计比较耗内存的
int strLen1(const char *s)  
{
    const char *t;
    for (t=s; *t!='\0'; ++t);
    return t-s;
}
char *strCpy(char *dest,const char *src)  
{
  assert(NULL!=dest);
  assert(NULL!=src); //两个条件可以用||合并,但不知错在哪个条件
    while (*src!='\0'){
      *dest=*src;
      dest++;
      src++;
    }
  *dest=*src; //此时等价于*dest='\0'; 
  //while ((*dest++ = *src++)!='\0');  //可合并为一行 
  return dest;
}  
char *strCpy1(char *dest,const char *src)
{
    char *p=dest;
    cout<<"begin copying:"<<endl;
    while (*src!='\0'){
    cout<<*src<<endl;
    *dest++=*src++;
  }
    *dest='\0';
    cout<<"end!"<<endl;
  return p;
}
int main()
{
    int len=0;
    char aChar;
    const char *str = "hello"; // 声明和赋值 
    //const 不能省,否则有警告提示,但能通过编译。警告内容如下:
    //[Warning] deprecated conversion from string constant to 'char*' [-Wwrite-strings]
    //可以用函数malloc()来分配空间,指定一个字串大小StringLength
    //char *s=(char*)malloc(StringLength*sizeof(char));
  cout<<str<<endl<<endl;
    cout<<"测试:sizeof()、strlen()"<<endl;
  const char msg1[] = "hello,world!hello,world!";
  len = strlen(msg1); //<cstring>库函数 
  cout<<sizeof(msg1)<<"|"<<len<<endl;  //sizeof 与 strlen 的区别,此时sizeof的值是数组的大小  
  len = strLen(msg1); //有大写字母的为自定义函数,以下同 
  cout<<sizeof(msg1)<<"|"<<len<<endl<<endl;
  //定义和赋值分开进行 
  const char *msg;
  msg = "hello,world!hello,world!";
  len = strlen(msg); //<cstring>库函数 
  cout<<sizeof(msg)<<"|"<<len<<endl;  //此时sizeof的值是指针的大小:64位系统是8;32位系统是4 
  len = strLen(msg); //有大写字母的为自定义函数,以下同 
  cout<<sizeof(msg)<<"|"<<len<<endl<<endl;
  //结论:sizeof不适合计算字符串长度 
    cout<<"测试:移动指针"<<endl;  
  cout<<msg<<endl;
  *msg++;*msg++;  //向后移动指针,对比显示的内容 
  aChar=*msg;
  cout<<&msg<<endl;  //取地址 
  cout<<*msg<<endl;
  cout<<aChar<<endl<<endl;
  *msg--;*msg--;  //向前移动指针,对比显示的内容
  aChar=*msg;
  cout<<&msg<<endl;
  cout<<*msg<<endl;
  cout<<aChar<<endl;
  cout<<*(msg+0)<<"="<<msg[0]<<endl;  
  cout<<*(msg+1)<<"="<<msg[1]<<endl;
  cout<<*(msg+2)<<"="<<msg[2]<<endl;  
  cout<<*(msg+3)<<"="<<msg[3]<<endl;
  cout<<*(msg+4)<<"="<<msg[4]<<endl;  
  cout<<*(msg+5)<<"="<<msg[5]<<endl;
  cout<<"["<<*(msg+strlen(msg))<<"]<-NULL/\'0\'"<<endl;
  cout<<msg<<endl<<endl;
  cout<<"测试:strcpy()"<<endl;
  for (int i=0;i<12;i++) *msg++; //源字串的长度必须不大于目标字串长度 
  cout<<msg<<endl;
  char dest[21]="ABCDEFGHIJKLMNOPQRST"; //20个字母+'\0' 
  cout<<"["<<dest<<"]:"<<sizeof(dest)<<"|"<<strlen(dest)<<endl;
    strcpy(dest,msg); //sizeof值未变,strlen值变小 
  cout<<"["<<dest<<"]:"<<sizeof(dest)<<"|"<<strlen(dest)<<endl; 
    strCpy(dest,msg);
  cout<<"["<<dest<<"]:"<<sizeof(dest)<<"|"<<strlen(dest)<<endl; 
    strCpy1(dest,msg);
  cout<<"["<<dest<<"]:"<<sizeof(dest)<<"|"<<strlen(dest)<<endl<<endl; 
  cout<<"测试:strncpy()"<<endl;
  char dest1[15]="abcdefghijklmn";
  strncpy(dest1,msg,strlen(msg));
  cout<<dest1<<endl;
  char dest2[10]={0}; //设一个最大长度可为10的空串 
  cout<<dest2<<"|"<<endl;
  strncpy(dest2,msg,strlen(dest2)); //没复制到内容 
  cout<<dest2<<"|"<<endl;
  strncpy(dest2,msg,sizeof(dest2)); //只能复制到10个字符 
  cout<<dest2<<endl;
  strncpy(dest2,msg,strlen(msg)); //可以得到12个字符,但后2个越界
  cout<<dest2<<"|"<<sizeof(dest2)<<"|"<<strlen(dest2)<<endl;
  //结论:dest必须有足够的空间来容纳source的字符长度+'\0';相比strcpy更容易溢出出错弃用,建议用strncpy
    return 0;
}



测试结果:

hello
测试:sizeof()、strlen()
25|24
25|24
8|24
8|24
测试:移动指针
hello,world!hello,world!
0x22fe08
l
l
0x22fe08
h
h
h=h
e=e
l=l
l=l
o=o
,=,
[]<-NULL/'\0'
hello,world!hello,world!
测试:strcpy()
hello,world!
[ABCDEFGHIJKLMNOPQRST]:21|20
[hello,world!]:21|12
[hello,world!]:21|12
begin copying:
h
e
l
l
o
,
w
o
r
l
d
!
end!
[hello,world!]:21|12
测试:strncpy()
hello,world!mn
|
|
hello,worl
hello,world!|10|12
--------------------------------
Process exited after 1.042 seconds with return value 0
请按任意键继续. . .


指针减法运算:


两个指针相减的结果的类型是ptrdiff_t,它是一种有符号整数类型。减法运算的值是两个指针在内存中的距离(以数组元素的长度为单位,而不是以字节为单位)与数组中存储的元素的类型无关,因为减法运算的结果已经将地址的差值除以该类型占用内存的长度。例如,如果p1指向array[i],而p2指向array[j],那么p2-p1的值就是j-i的值。


另外:void*类型的指针之间不能进行减法运算!指针可以加减一个整数表示指针偏移,但指针之间只有减法,没有加、乘、除法。




题外话:递归求串长的最大长度


测试:见如下代码maxSize增加到一定大比如说70000,递归法的strLen()就不行了,库函数和另外两种方法都没问题。估计maxSize的值在不同机器不同平台上可能会有不同;也有可能同一环境下不同时时间点都有可以不同。


#include<iostream>
#include<cstring>
int strLen(const char *s)
{
  if (*s) return (1+strLen(s+1)); else return 0;
}
int strLEN1(const char *s)
{
    int i=0; while(*s++!='\0') i++;
    return i;  
}  
int strLEN2(const char *s)
{
    const char *t=s;
    while(*t) *t++;
    return t-s; 
}  
int main(void)
{
  int maxSize=43210;
  char *str=(char*)malloc(maxSize+1);
  for (int i=0;i<maxSize;i++) *(str+i)=(i%10)+'0';
  std::cout<<str<<std::endl;
  std::cout<<"{"<<strlen(str)<<"}"<<std::endl;
  std::cout<<"["<<strLEN1(str)<<"]"<<std::endl;
  std::cout<<"["<<strLEN2(str)<<"]"<<std::endl;
  std::cout<<"("<<strLen(str)<<")"<<std::endl;
  return 0;
}



连接、比较

#include <iostream>
#include <cstring>
using namespace std;
char *strCat(char *dest,const char *src)  
{
  char *p=dest;
  while (*dest) *dest++; //与strCpy比只多此行,目标串指针移到尾部然后复制源串 
  while ((*dest++ = *src++)!='\0'); 
  return p;
}  
char *strnCat(char *dest,const char *src,int n)
{
  char *p=dest;
  if (n>0){
    while (*dest) *dest++;
    while ((*dest++ = *src++)!='\0')
      if (!--n) break;  //与strCat比,增加条件--n==0退出 
    *dest='\0';
  }
  return p; //n非正整数直接返回目标串 
}
int strCmp(const char *s1,const char *s2)  
{  
    int ret=0;
    while (!(ret=*s1++-*s2) && *s2++);
    if (ret<0) ret=-1;
  else if (ret>0) ret=1;
    return(ret);
} 
int main()
{
    char str1[20] = "hello";
    const char *str2 = ",world!"; 
    cout<<"测试:strcat()"<<endl;
    cout<<"str1:"<<str1<<endl;
  cout<<strcat(str1,str2)<<endl;
  cout<<"str1:"<<str1<<endl<<endl;
    cout<<"测试:strCat()"<<endl;
  str1[5]='\0'; //复原str1 
  cout<<"str1:"<<str1<<endl;
  cout<<strCat(str1,str2)<<endl;
  cout<<"str1:"<<str1<<endl<<endl;
    cout<<"测试:strncat(s1,s2,i) i=0~8"<<endl;
  for (int i=0;i<9;i++){
  str1[5]='\0';
  cout<<"str1:"<<str1<<endl;
  cout<<strncat(str1,str2,i)<<endl;
  cout<<"str1:"<<str1<<endl<<endl;
  }
    cout<<"测试:strnCat(s1,s2,i) i=0~8"<<endl;
  for (int i=0;i<9;i++){
    str1[5]='\0';
    cout<<"str1:"<<str1<<endl;
    cout<<strnCat(str1,str2,i)<<endl;
    cout<<"str1:"<<str1<<endl<<endl;
  }
  //注意:目标串的空间 必须可容纳 目标串+源串的长度 + 1('\0') 个字符 
  cout<<"测试:strcmp()"<<endl;
    cout<<"str1>str2"<<"|"<<strcmp(str1,str2)<<endl;
    cout<<"str1=str1"<<"|"<<strcmp(str1,str1)<<endl;
    cout<<"str2<str1"<<"|"<<strcmp(str2,str1)<<endl<<endl;
  cout<<"测试:strCmp()"<<endl;
    cout<<"str1>str2"<<"|"<<strCmp(str1,str2)<<endl;
    cout<<"str1=str1"<<"|"<<strCmp(str1,str1)<<endl;
    cout<<"str2<str1"<<"|"<<strCmp(str2,str1)<<endl;
    return 0;
}


测试结果:

测试:strcat()
str1:hello
hello,world!
str1:hello,world!
测试:strCat()
str1:hello
hello,world!
str1:hello,world!
测试:strncat(s1,s2,i) i=0~8
str1:hello
hello
str1:hello
str1:hello
hello,
str1:hello,
str1:hello
hello,w
str1:hello,w
str1:hello
hello,wo
str1:hello,wo
str1:hello
hello,wor
str1:hello,wor
str1:hello
hello,worl
str1:hello,worl
str1:hello
hello,world
str1:hello,world
str1:hello
hello,world!
str1:hello,world!
str1:hello
hello,world!
str1:hello,world!
测试:strnCat(s1,s2,i) i=0~8
str1:hello
hello
str1:hello
str1:hello
hello,
str1:hello,
str1:hello
hello,w
str1:hello,w
str1:hello
hello,wo
str1:hello,wo
str1:hello
hello,wor
str1:hello,wor
str1:hello
hello,worl
str1:hello,worl
str1:hello
hello,world
str1:hello,world
str1:hello
hello,world!
str1:hello,world!
str1:hello
hello,world!
str1:hello,world!
测试:strcmp()
str1>str2|1
str1=str1|0
str2<str1|-1
测试:strCmp()
str1>str2|1
str1=str1|0
str2<str1|-1
--------------------------------
Process exited after 1.034 seconds with return value 0
请按任意键继续. . .


结论:C语言风格字符串使用麻烦,需要自己分配空间,就连最简单的字串连接操作还要担心是否越界,而string类只要用“加法+”就行了。所以不建议用<cstring>字符串,强烈推荐使用string类,头文件<string>,Dev-C++中可以不用#include。后者字符串操作函数比较丰富,且使用方便:


strlen(s) <=> s.length() 或 s.size()、strcat(s1,s2) <=> s1.append(s2) 、strncpy(s1,s2,n) <=> s1=s2.substr(0,n)等等。还与C字符串可以双向转换:

#include <iostream>
int main(void)
{
  //C字符串 转 string类 
    const char *s1 = "hello";
  std::string s2 = std::string(s1);
    std::cout<<s2<<std::endl;
    //string类 转 C字符串 
    std::string s3 = "world";
  char *s4 = (char*) s3.data(); //或 .c_str()
  std::cout<<s4<<std::endl;
    return 0;
}

附录一:


string类


【以下内容来源:百度百科】


string是以char作为模板参数的模板类实例,把字符串的内存管理责任由string负责而不是由编程者负责,大大减轻了C语言风格的字符串的麻烦。


std::basic_string提供了大量的字符串操作函数,如比较、连接、搜索、替换、获得子串等。


std::basic_string属于C++ STL容器类,用户自定义的类也可以作为它的模板参数,因此也适用C++ STL Algorithm库。


string本质上是以字符作为元素的vector特化版本;不存在0字符结尾这个概念,能装入'\0'这种数据。



成员函数


下面列出所有成员函数,其中string是std::basic_string<T>的简写:


构造表示


string::string(构造)

string::~string(析构)

string::operator=- 赋值

string::assign–赋值

string::get_allocator–获得内存分配器


字符访问


string::at–访问特定字符,带边界检查

string::operator[]–访问特定字符

string::front–访问第一个字符

string::back–访问最后一个字符

string::data–访问基础数组,C++11 后与 c_str() 完全相同

string::c_str–返回对应于字符串内容的 C 风格零结尾的只读字符串

string::substr–以子串构造一个新串;参数为空时取全部源串


迭代器


string::begin–获得指向开始位置的迭代器

string::end–获得指向末尾的迭代器

string::rbegin–获得指向末尾的逆向迭代器

string::rend–获得指向开始位置的逆向迭代器

string::cbegin–获得指向开始位置的只读迭代器

string::cend–获得指向末尾的只读迭代器

string::crbegin–获得指向末尾的逆向只读迭代器

string::crend–获得指向开始位置的逆向只读迭代器


容量


string::empty–检查是否为空

string::size–返回数据的字符长度

string::length–返回数据的字符长度,与 size() 完全相同

string::max_size–返回可存储的最大的字节容量,在 32 位 Windows 上大概为 43 亿字节。

string::reserve–改变 string 的字符存储容量,实际获得的存储容量不小于 reserve 的参数值。

string::capacity–返回当前的字符存储容量

string::shrink_to_fit(C++11新增)–降低内存容量到刚好


修改器


string::clear–清空内容

string::insert–插入字符或字符串。目标 string 中的插入位置可用整数值或迭代器表示。如果参数仅为一个迭代器,则在其所指位置插入0值。

string::erase–删除 1 个或 1 段字符

string::push_back–追加 1 个字符

string::pop_back–删除最后 1 个字符,C++11 标准引入

string::append–追加字符或字符串

string::operator+=–追加,只有一个参数——字符指针、字符或字符串;不像 append() 一样可以追加参数的子串或若干相同字

string::copy–拷贝出一段字符到 C 风格字符数组;有溢出危险

string::resize–改变(增加或减少)字符串长度;如果增加了字符串长度,新字符缺省为 0 值

string::swap–与另一个 string 交换内容

string::replace–替换子串;如果替换源数据与被替换数据的长度不等,则结果字符串的长度发生改变



搜索


string::find–前向搜索特定子串的第一次出现

string::rfind–从尾部开始,后向搜索特定子串的第一次出现

string::find_first_of–搜索指定字符集合中任意字符在 *this 中的第一次出现

string::find_last_of–搜索指定字符集合中任意字符在 *this 中的最后一次出现

string::find_first_not_of–*this 中的不属于指定字符集合的首个字符

string::find_last_not_of–*this 中的不属于指定字符集合的末个字符

string::compare–与参数字符串比较




常量值

  • string::npos–表示“未找到”,值为static const unsigned -1



非成员的有关的全局函数


std::operator+–字符串连接

std::operator!=–不等比较

std::operator==–相等比较

std::operator<–小于比较

std::operator<=–小于等于比较

std::operator>–大于比较

std::operator>=–大于等于比较

std::operator<<–字符串内容写到输出流中

std::operator>>–从输入流中读取一个字符串

std::getline–从istream中读入一行或一段字符到string中

std::swap–交换两个string的内容。是std::swap算法针对std::basic_string的特化版本

std::stoi–字符串转为整形

std::stol–字符串转为长整形

std::stoll–字符串转为长长整形

std::stoul–字符串转为无符号长整形

std::stoull–字符串转为无符号长长整形

std::stof–字符串转为单精度浮点形

std::stod–字符串转为双精度浮点形

std::stold–字符串转为长双精度浮点形

std::to_string–整型、无符号整型、浮点型转化为string

std::to_wstring–整型、无符号整型、浮点型转化为wstring



附录二:


复制函数

char *strcpy(char *s1, const char *s2);
char *strncpy(char *s1, const char *s2, size_t n);
void *memcpy(void *s1, const void *s2, size_t n);
void *memmove(void *s1, const void *s2, size_t n);


strcpy,strcpy,memcpy,memmove的第一个参数都为复制的dest,而第二个参数都为复制的源source。


strcpy将一个以空字符结尾的字符串s2复制给s1。strncpy跟strcpy一样,只不过它限制了复制的字符的个数,最多复制n个字符。如果n过小,那么strncpy就不能复制末尾的空字符,如果n比源字符串长度大,strncpy在遇到空字符后会不断向目的字符串追加空字符,直到达到n个。同时strcpy和strncpy在源和目的重叠时也会有问题的。


memcpy函数从字节数组s2向s1复制n个字节。如果源和目的有重叠,那么使用memcpy会有问题。memmove函数可以在源和目的重合时正常处理,在其他方面与memcpy相同。


memcpy、memmove和strncpy函数可用于包括字符在内的任何内存块,而strcpy函数只适合字符串,它会持续复制字符,直到遇到源字符中的空字符为止。



拼接函数

1. char *strcat(char *s1, const char *s2);
2. char *strncat(char *s1, const char *s2, size_t n);



  • strcat函数将它的第二个参数s2追加到第一个参数s1的末尾。s1s2必须都是以空字符结尾的字符串。strcat会用s2的第一个字符覆盖s1的空字符,并在拼接字符串的后边添加空字符。
  • strncatstrcat功能相同,只是限制了从s2中取出拼接到s1的字符个数。



比较函数

int memcmp(const void *s1, const void *s2, size_t n);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
int stricmp(const char *s1, const char *s2);
int strnicmp(const char *s1, const char *s2, size_t n); 
int strcoll(const char *s1, const char *s2);
size_t strxfrm(char *s1, const char *s2, size_t n);



memcmp,strcmp,strncmp,stricmp,strnicmp函数以指向字符(字节)数组的指针为参数,逐个比较两个字符(字节)数组的每个字符。根据比较结束时第一个字符(字节)数组中的字符(字节)是小于、等于或大于第二个字符(字节)数组中的字符(字节)而返回-1,0或1。三个函数的主要区别是在于何时结束比较,如果第一个不同的字符在memcmp和strncmp的范围n之内,则三者相同。否则,strcmp在遇到空字符停止比较,memcmp不关心空字符,在比较的字节数达到n个时停止比较,strncmp结合了上述两个函数的特点,在达到n个字符或遇到空字符时停止比较。


stricmp,strnicmp和strcmp,strncmp功能相似,只不过以大小写不敏感的方式进行比较。


strcroll和strcmp功能相似,只不过比较结果依赖于本地化设置(根据不同的地点比较结果不同)。然而strcoll函数的速度不是很快,当这是个问题或者希望在改变本地设置而不影响比较结果的话,可以使用strxfrm函数,strxfrm将第二个参数进行本地化转换,并将转换结果放在第一个参数,参数n限制了转换的字符个数。




搜索函数

void *memchr(const void *s, int c, size_t n);
char *strchr(const char *s, int c);
char *strrchr(const char *s, int c);
char *strpbrk(const char *s1, const char *s2);
size_t strcspn(const char *s1, const char *s2); 
size_t strspn(const char *s1, const char *s2);
char *strstr(const char *s1, const char *s2);
char *strtok(char *s1, const char *s2);


strchr函数在字符串s中搜索字符c,它会返回一个指向s中第一个字符c的指针,如果没找到,则返回空指针。当遇到空字符时停止搜索。  


memchr函数在搜索了n个字符后停止搜索,返回第一个字符c的指针,若未找到,则返回空指针。  

strrchr与strchr类似,只是从字符串s的空字符开始,反向搜索字符c。如果找到,则返回反向第一个字符c的地址,若未找到返回空指针。  


strpbrk函数从s1中寻找与s2中任意一个字符匹配的第一个字符,并返回指向它的指针。若找不到,则返回空。  


strspn函数从字符串s1中搜索字符集s2,并返回字符组中第一个不属于给定字符集中的字符的下标,而strcspn函数返回第一个属于给定字符集中的字符的下标。  


strstr函数在字符串s1中搜索字符串s2,返回找到的第一处匹配子串的指针,如果找不到,则返回空。  

strtok函数在s1中搜索,查找一个非空字符序列(称作记号),这个序列不包括s2中指定的字符。将找到的记号后面的那个字符替换为一个空字符标记该记号的末尾,然后返回一个指向该记号的首字符的指针。使用

strtok(NULL,s2)就可以继续上一次的strtok函数调用,直到其返回一个空指针为止。



其他函数

1. void *memset(void *s, int c, size_t n);
2. size_t strlen(const char *s);
3. char *strerror(int errnum);



  • memset函数将一个字符的多个副本存储到指定的内存区域。
  • strlen返回字符串的长度,不包括字符串末尾的空字符。
  • strerror当输入存储在errno的错误码时,会返回一个指向描述这种错误的字符串的指针。


目录
相关文章
|
1天前
|
存储 安全 Linux
网络请求的高效处理:C++ libmicrohttpd库详解
网络请求的高效处理:C++ libmicrohttpd库详解
|
2天前
|
消息中间件 存储 开发工具
消息队列 MQ产品使用合集之C++如何使用Paho MQTT库进行连接、发布和订阅消息
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
4天前
|
编译器 C++
【C++】类和对象③(类的默认成员函数:赋值运算符重载)
在C++中,运算符重载允许为用户定义的类型扩展运算符功能,但不能创建新运算符如`operator@`。重载的运算符必须至少有一个类类型参数,且不能改变内置类型运算符的含义。`.*::sizeof?`不可重载。赋值运算符`=`通常作为成员函数重载,确保封装性,如`Date`类的`operator==`。赋值运算符应返回引用并检查自我赋值。当未显式重载时,编译器提供默认实现,但这可能不足以处理资源管理。拷贝构造和赋值运算符在对象复制中有不同用途,需根据类需求定制实现。正确实现它们对避免数据错误和内存问题至关重要。接下来将探讨更多操作符重载和默认成员函数。
|
4天前
|
程序员 编译器 C++
探索C++语言宝库:解锁基础知识与实用技能(类型变量+条件循环+函数模块+OOP+异常处理)
探索C++语言宝库:解锁基础知识与实用技能(类型变量+条件循环+函数模块+OOP+异常处理)
8 0
|
6天前
|
域名解析 网络协议 程序员
程序员必知:【转】adns解析库——域名解析实例(C++、linux)
程序员必知:【转】adns解析库——域名解析实例(C++、linux)
13 0
|
6天前
|
C++ 容器
C++ STL标准库 《map容器详解》
C++ STL标准库 《map容器详解》
11 0
|
6天前
|
存储 C++ 容器
C++ STL标准库 《map容器详解》
C++ STL标准库 《map容器详解》
13 0
|
6天前
|
缓存 C++
详细解读C++常用库函数C函数库cstdio
详细解读C++常用库函数C函数库cstdio
|
6天前
详细解读C++char类型函数
详细解读C++char类型函数
12 0
|
1天前
|
编译器 C语言 C++