《一》,字符指针&字符数组
两者形式:
字符指针:char *p;
字符数组:char str[100];
两者区别:
字符指针p是变量;
字符数组str是常量;
访问元素方式:
字符指针:*(p+i) || p[i], 访问第i个元素;
字符数组:*(str+i) || str[i] 访问第i个元素;
利用 sizeof() 求大小:
字符指针: sizeof(p) = 4, sizeof(p)求的是指针p所占的空间,恒为4字节;
字符数组: sizeof(str) = 100, sizeof(str)求的是数组str的真实空间,100;
字符串函数strlen()说明:
strlen()仅仅求出字符串中第一个'\0'之前的字符个数,
printf("%s",str)只输出第一个'\0'之前的字符个数;
函数原型:
int strlen(char *p)
{
int count=0;
if(p==NULL)
return count;
while(*p++ != '\0')
count++;
return count;
}
简单实例:
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #define _CRT_SECURE_NO_WARNINGS //关闭安全检查 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 6 //for语句 7 int mystrlen(char* str) 8 { 9 int i = 0; 10 for (char*p = str; *p != '\0'; p++) 11 { 12 i++; 13 } 14 return i;//实现字符串统计 15 } 16 17 //go语句 18 int mystrlenA(char* str) 19 { 20 char *p = str; 21 int i = 0; 22 AAA: if (*p!='\0') 23 { 24 i++; 25 p++; 26 goto AAA; 27 } 28 return i; 29 } 30 31 32 //递归实现 33 int mystrlenB(char *str) 34 { 35 if (*str=='\0') 36 { 37 return 0; 38 } 39 else 40 { 41 return 1 + mystrlenB(++str); 42 } 43 44 45 } 46 47 48 49 void main() 50 { 51 char str[100] = "china is good"; 52 char *p = str; 53 char *q = malloc(sizeof(char)*50); 54 q = "hello,i am q"; 55 printf("str:%s",str); 56 printf("\nsizeof(str):%d", sizeof(str)); 57 printf("\nstrlen(str):%d", strlen(str)); 58 printf("\n\np:%s", p); 59 printf("\nsizeof(p):%d", sizeof(p)); 60 printf("\nstrlen(p):%d", strlen(p)); 61 printf("\n\nq:%s", q); 62 printf("\nsizeof(q):%d", sizeof(q)); 63 printf("\nstrlen(q):%d", strlen(q)); 64 65 printf("\n%d", mystrlen(str));//从开头第一个字符到\0字符 66 printf("\n%d", mystrlenA(str)); 67 printf("\n%d", mystrlenB(str)); 68 69 getchar(); 70 }
运行结果:
《二》
字符串库实现:
String.h
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 6 //字符串封装,需要库函数 7 //不需要库函数 8 struct CString 9 { 10 char *p;//保存字符串首地址 11 int reallength;//实际长度 12 }; 13 typedef struct CString mystring;//简写 14 15 //字符串,初始化,打印, 16 //查找,查找字符,查找字符串 17 //尾部增加,(字符,字符串) 18 //删除(字符,字符串), 19 //任意位置增加(字符,字符串) 20 21 22 ////修改字符串,(字符,字符串替换) 23 24 void init(mystring *string);//原封不动初始化 25 void initwithlength(mystring *string,int length);//开辟长度,内存清零 26 void initwithstring(mystring *string,char *copystring);//初始化并拷贝字符串 27 void printfstring(mystring *string); //打印 28 void backaddchar(mystring *string,char ch);//增加字符 29 void backaddstring(mystring *string,char*str);//增加字符串 30 void run(mystring *string);//执行指令 31 char * findfirstchar(mystring *string, char ch);//返回第一个找到的字符的地址 32 char * findfirststring(mystring *string, char *str);//返回第一个找到的字符串的地址 33 int deletefirstchar(mystring *string,const char ch);//删除第一个找到的字符 34 int deletefirststring(mystring *string, char * const str);//删除第一个找到的字符串 35 void addchar(mystring *string, char ch,char *pos);//任意增加字符 36 void addstring(mystring *string, char*str,char *pos);//任意增加字符串 37 void changefirstchar(mystring *string, const char oldchar, const newchar);//改变字符 38 void changefirststring(mystring *string, char * const oldstring, char *const newstring);//改变字符串
String.c
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include"字符串.h" 2 3 int mystrlen(char *p) 4 { 5 if (p == NULL) 6 { 7 return -1;//失败, 8 } 9 int length = 0; 10 while (*p != '\0')//字符串终止条件 11 { 12 length++;//长度自增 13 p++;//指针不断向前 14 } 15 return length; 16 17 } 18 char *mystrcpy(char *dest, const char *source)//const限定不被意外修改 19 { 20 if (dest == NULL || source == NULL) 21 { 22 return NULL;//为空没有必要干活了 23 } 24 char * destbak = dest; 25 while (*source != '\0')//一直拷贝 26 { 27 *dest = *source;//赋值字符 28 source++; 29 dest++;//指针不断向前,字符挨个赋值 30 } 31 *dest = '\0';//结尾 32 return destbak;//返回地址 33 34 } 35 36 char *mystrcat(char *dest, const char *source) 37 { 38 if (dest == NULL || source == NULL) 39 { 40 return NULL;//失败 41 } 42 else 43 { 44 char *destbak = dest;//保留地址 45 while (*dest != '\0') 46 { 47 dest++;//指针向前移动 48 } 49 //从尾部开始拷贝 50 while (*source != '\0') //循环被被拷贝的字符串 51 { 52 *dest = *source;//字符串赋值 53 dest++; 54 source++; 55 56 } 57 *dest = '\0';//结尾 58 return destbak; 59 60 } 61 62 63 64 } 65 66 char * mystrchr(const char *dest, const char ch) 67 { 68 if (dest == NULL) 69 { 70 return NULL; 71 } 72 73 while (*dest!='\0') 74 { 75 if (*dest == ch) 76 { 77 return dest;//找到返回地址 78 } 79 dest++; 80 } 81 return NULL;//返回 82 83 } 84 85 char *mystrstr(const char * const dest, const char * const findstr) 86 { 87 if (dest == NULL || findstr == NULL) 88 { 89 return NULL; 90 } 91 char *destbak = dest; 92 char *p = NULL;//保存找到的地址 93 while (*destbak != '\0') 94 { 95 int flag = 1;//假定是相等 96 char *findstrbak = findstr; 97 char *nowdestbak = destbak; 98 while (*findstrbak != '\0') 99 { 100 if (*nowdestbak != '\0') 101 { 102 103 if (*findstrbak != *nowdestbak)//有一个不等 104 { 105 flag = 0;//赋值为0代表不等 106 } 107 nowdestbak++; 108 findstrbak++; 109 } 110 else 111 { 112 flag = 0;//设置标识 113 break; 114 } 115 116 } 117 if (flag == 1) 118 { 119 p = destbak;//当前位置 120 return p; 121 } 122 123 destbak++; 124 } 125 126 return NULL; 127 128 } 129 130 131 132 133 134 void init(mystring *string) 135 { 136 string->p = NULL; 137 string->reallength = 0;//初始化结构体字符串 138 } 139 void initwithlength(mystring *string, int length) 140 { 141 //string->p =(char *) malloc(sizeof(char)*length);//分配内存 142 string->p = (char *)calloc(length, sizeof(char));//分配内存并清零 143 string->reallength = length;//长度 144 145 146 } 147 void initwithstring(mystring *string, char *copystring) 148 { 149 int length = strlen(copystring);//获取字符串长度 150 string->p =(char *) calloc(length + 1, sizeof(char));//分配内存 151 mystrcpy(string->p, copystring);//拷贝字符串 152 string->reallength = length + 1;//设置长度 153 154 } 155 void backaddchar(mystring *string,char ch) 156 { 157 158 if (mystrlen(string->p)+1==string->reallength)//意味着满了 159 { 160 //重新分配内存 161 string->p = realloc(string->p, string->reallength + 1); 162 string->reallength += 1; 163 string->p[string->reallength - 2] = ch; 164 string->p[string->reallength - 1] = '\0'; 165 166 } 167 else 168 { 169 int nowlength = mystrlen(string->p);//求出当前长度 170 string->p[nowlength] = ch; 171 string->p[nowlength + 1] = '\0';//字符的增加 172 173 } 174 175 } 176 void backaddstring(mystring *string, char*str) 177 { 178 int nowmystringlength = mystrlen(string->p);//获取当前长度 179 int addstringlength = mystrlen(str);//要增加的长度 180 if (nowmystringlength + addstringlength+1 >string->reallength)//判定是否越界 181 { 182 int needaddlength = nowmystringlength + addstringlength + 1 - (string->reallength); 183 //printf("%d", needaddlength); 184 string->p = (char *)realloc(string->p, string->reallength + needaddlength);//增加字符串长度 185 mystrcat(string->p, str);//拷贝字符串 186 string->reallength += needaddlength;//增加长度 187 188 } 189 else 190 { 191 mystrcat(string->p, str);//拷贝字符串 192 193 194 195 } 196 197 198 199 } 200 void printfstring(mystring *string) 201 { 202 203 printf("\nstring=%s", string->p);//打印字符串 204 205 } 206 void run(mystring *string) 207 { 208 209 system(string->p);//执行指令 210 } 211 212 char * findfirstchar(mystring *string, char ch) 213 { 214 char *p = mystrchr(string->p, ch);//查找 215 return p; 216 217 } 218 char * findfirststring(mystring *string, char *str) 219 { 220 221 char *pres = mystrstr(string->p, str); 222 return pres;//返回地址 223 224 } 225 int deletefirstchar(mystring *string, const char ch) 226 { 227 228 char *p = mystrchr(string->p, ch);//查找 229 if (p == NULL) 230 { 231 return 0; 232 233 } 234 else 235 { 236 237 char *pnext = p + 1; 238 while (*pnext != '\0') 239 { 240 *p = *pnext; //删除一个字符整体向前移动 241 p++; 242 pnext++; 243 } 244 *p = '\0';//字符串要有结尾 245 return 1; 246 } 247 248 249 250 251 } 252 int deletefirststring(mystring *string, char * const str) 253 { 254 char *pres = mystrstr(string->p, str);//查找 255 if (pres == NULL) 256 { 257 return 0; 258 259 } 260 else 261 { 262 int length = mystrlen(str);//求字符串长度 263 char *pnext = pres + length;//下一个字符 264 while (*pnext != '\0') 265 { 266 *pres = *pnext; //删除一个字符整体向前移动 267 pres++; 268 pnext++; 269 270 } 271 *pres = '\0';//字符串要有结尾 272 return 1; 273 } 274 275 276 277 } 278 279 280 void addchar(mystring *string, char ch, char *pos) 281 { 282 if (pos == NULL || string ==NULL) 283 { 284 return; 285 } 286 if(mystrlen(string->p) + 1 == string->reallength)//意味着满了 287 { 288 //重新分配内存 289 string->p = realloc(string->p, string->reallength + 1); 290 string->reallength += 1; 291 292 int nowlength = mystrlen(string->p);//求出当前长度 293 int movelength = mystrlen(pos);//求出现在要移动的长度 294 for (int i = nowlength; i > nowlength - movelength; i--)//移动 295 { 296 string->p[i] = string->p[i - 1];//轮询 297 } 298 string->p[nowlength - movelength] = ch;//插入 299 300 string->p[nowlength + 1] = '\0';//结尾 301 302 } 303 else 304 { 305 int nowlength = mystrlen(string->p);//求出当前长度 306 int movelength = mystrlen(pos);//求出现在要移动的长度 307 for (int i = nowlength; i > nowlength-movelength; i--)//移动 308 { 309 string->p[i] = string->p[i - 1];//轮询 310 } 311 string->p[nowlength - movelength]=ch;//插入 312 string->p[nowlength + 1] = '\0';//结尾 313 314 315 316 317 318 } 319 320 321 322 } 323 void addstring(mystring *string, char*str, char *pos)//任意增加字符串 324 { 325 if (pos == NULL || string == NULL) 326 { 327 return; 328 } 329 int nowmystringlength = mystrlen(string->p);//获取当前长度 330 int addstringlength = mystrlen(str);//要增加的长度 331 if (nowmystringlength + addstringlength + 1 >string->reallength)//判定是否越界 332 { 333 int needaddlength = nowmystringlength + addstringlength + 1 - (string->reallength); 334 //printf("%d", needaddlength); 335 string->p = (char *)realloc(string->p, string->reallength + needaddlength);//增加字符串长度 336 string->reallength += needaddlength;//增加长度 337 338 //先移动,再拷贝 339 int nowlength = mystrlen(string->p);//求出当前长度 340 int movelength = mystrlen(pos);//求出现在要移动的长度 341 int insertlength = strlen(str);//要求出插入的长度 342 343 for (int i = nowlength; i >=nowlength-movelength ; i--) 344 { 345 string->p[i + insertlength]=string->p[i];//字符移动 346 } 347 for (int j = 0; j < insertlength;j++) 348 { 349 string->p[nowlength-movelength+j]= str[j];//赋值拷贝 350 } 351 352 } 353 else 354 { 355 int nowlength = mystrlen(string->p);//求出当前长度 356 int movelength = mystrlen(pos);//求出现在要移动的长度 357 int insertlength = strlen(str);//要求出插入的长度 358 for (int i = nowlength; i >= nowlength - movelength; i--) 359 { 360 string->p[i + insertlength] = string->p[i];//字符移动 361 } 362 for (int j = 0; j < insertlength; j++) 363 { 364 string->p[nowlength - movelength + j] = str[j];//赋值拷贝 365 } 366 367 // 368 369 370 371 } 372 373 374 } 375 void changefirstchar(mystring *string, const char oldchar, const newchar)//改变字符 376 { 377 char *pstr = string->p; 378 while (*pstr != '\0') 379 { 380 if (*pstr == oldchar)//查找 381 { 382 *pstr = newchar;//赋值 383 return; 384 } 385 pstr++; 386 } 387 388 } 389 void changefirststring(mystring *string, char * const oldstring, char *const newstring)//改变字符串 390 { 391 char *pfind = findfirststring(string, oldstring);//找到位置 392 if (pfind != NULL) 393 { 394 deletefirststring(string, oldstring);//删除 395 addstring(string, newstring, pfind);//插入 396 } 397 398 399 }
特别说明:《C Primer Plus》第五版 第10章有数组,指针,函数的详细讨论,11章详细介绍字符串·相关操作;