3 字符串
3.1 字符串操作:遍历、赋值、修改
int main(){
char s[] = "Hello World!";
// 字符串遍历1
char* q = s;
while('\0' != *q){
printf("%c",*q++);
}
printf("\n");
// 字符串遍历2
for(int i = 0;'\0' != s[i];i++){
printf("%c",s[i]);
}
printf("\n");
// 字符串赋值
char* p;
p = s; //字符串可以赋值给指针
// s = p; //指针不允许赋值给字符串
// 字符串修改
p[1] = 'A';
printf("%p\n%p\n",s,p);
printf("%s\t%s\n",s,p);
s[2] = 'L';
printf("%p\n%p\n",s,p);
printf("%s\t%s\n",s,p);
}
Hello World!
Hello World!
0x7ffc0789c4fb
0x7ffc0789c4fb
HAllo World! HAllo World!
0x7ffc0789c4fb
0x7ffc0789c4fb
HALlo World! HALlo World!
3.2 字符串与函数
- 字符串传参
字符串传参方式与数组传参方式一样,只不过很多时候不需要传递字符串的长度
两种传参方式:char* str / char str[]
void print_str(char* str){
printf("%s\n",str);
}
void print_str2(char str[]){
printf("%s\n",str);
}
int main(){
char str[] = "Hello World!";
print_str(str);
print_str2(str);
}
- 字符串返回
字符串返回只能使用指针char*
str1和str2拼接
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* Strcat(char* s1,char* s2){
char *s = malloc(strlen(s1)+strlen(s2)+1);
int k = 0;
for(int i = 0;s1[i] != '\0';i++){
s[k++] = s1[i];
}
for(int i = 0;s2[i] != '\0';i++){
s[k++] = s2[i];
}
return s;
}
int main(){
char str1[] = "Hello";
char str2[] = "World";
char* s = Strcat(str1,str2);
printf("%s\n",s);
}
字符拼接2
#include <stdio.h>
char* Strcat(char* s1,char* s2){
char* res = s1;
while('\0' != *s1){
++s1;
}
while('\0' != *s2){
*s1++ = *s2++;
}
*s1 = '\0';
return res;
}
int main(){
char str1[11] = "Hello";
char str2[] = "World";
char* s = Strcat(str1,str2);
printf("%s\n",s);
}
3.3 字符串指针
数组可以用指针表示
字符数组可以直接初始化字符数组,并且可以赋值给指针。
#include <stdio.h>
int main(){
char s[] = "Hello World";
char* p = s;
printf("%s\n",p);
}
字符串也可以直接赋值给指针,这种指针成为字符串指针
#include <stdio.h>
int main(){
char* s = "Hello World";
printf("%s\n",s);
}
3.4 字符串指针 vs 字符数组
1、sizeof与strlen()
2、字符是否可修改
3、地址是否可修改
#include <stdio.h>
#include <string.h>
int main(){
char* s = "Hello World";
char s1[] = "Hello World";
printf("%d\t%d\n",sizeof(s),strlen(s));
printf("%d\t%d\n",sizeof(s1),strlen(s1));
}
8 11 sizeof(s)为指针s的长度,strlen(s)为字符串的长度
12 11 sizeof(s1)为字符串s1的长度(包含'\0'),strlen(s1)为字符串的长度
- 2、字符是否可修改
字符串指针的元素不可以修改
字符数组的元素可以修改
char* s = "Hello World";
char s1[] = "Hello World";
//*(s+2) = 'L'; //字符串指针不支持修改元素
s1[2] = 'L'; //字符数组可以修改元素
printf("%s\n%s\n",s,s1);
//等价
char s[] = "Hello World";
char s[]={'H','e','l','l','o',' ','W','o','r','l','d','\0'};
//等价
char* s = "Hello World";
const char t[]="Hello World"; //看作const型,所以无法修改元素
char* s = t;
- 3、地址是否可修改
字符串指针内容可以整体修改
字符串数组内容无法整体修改
#include <stdio.h>
#include <string.h>
int main(){
char* p = "Hello";
char s[] = "Hello";
p = "World"; //可以修改
// s = "World"; //无法修改
printf("%s\n%s\n",p,s);
}
- 字符串指针和字符数组如何选择
1、如果需要构造字符串使用数组;如果需要处理字符串使用指针(指向字符数组的指针)。
2、字符串不需要修改,使用字符串字面量初始化字符串指针。
3、字符串需要修,改使用字符串字面量初始化字符数组。
3.5 字符串const
- const字符数组
- 指向const字符是数组的字符串指针
#include <stdio.h>
#include <string.h>
int main(){
const char s[] = "Hello World";
//s[0] = 'h'; //不可修改
//s[6] = 'w';
char* p = s;
printf("%s\n%s\n",s,p);
*(p+6) = 'w'; //可修改
*p = 'h';
printf("%s\n%s\n",s,p); //s和p均被修改
}
Hello World
Hello World
hello world
hello world
结论:决定能否修改的是指针指向的值能否修改,const的限制只针对对应为const的变量。
3.6 字符串函数
int strcmp(const char* s1,const char* s2)
s1>s2,返回值>0;
s1<s2,返回值<0;
s1==s2,返回值为0.
char* strcpy(char* restrict dst,const char* restrict src);
返回值为dst
#include <stdio.h>
#include <string.h>
int main(){
char dst[3] = "cd";
const char* src = "ab";
char* res = strcpy(dst,src);
printf("%s\t%s\n",dst,res);
printf("%p\t%p\n",dst,res);
}
ab ab
0x7ffd7f72fbbd 0x7ffd7f72fbbd
#include <stdio.h>
#include <string.h>
int main(){
char dst[3] = "cd";
const char* src = "ab";
strcpy(dst,src);
printf("%s\n",dst);
}
ab
#include <stdio.h>
#include <string.h>
int main(){
char* a = "hello";
const char* b = "world";
char res[11];
strcat(strcat(res,a),b);
printf("%s\n",res);
}
strcpy和strcat都会有安全问题:dst空间不足,出现越界。
#include <stdio.h>
#include <string.h>
int main(){
const char* s1 = "abcdef";
const char* s2 = "cd";
char* c = strstr(s1,s2);
printf("%s\n",c);
printf("%p\t%p\n",c,s1+2);
}
cdef
0x40072a 0x40072a
返回地址为s2在s1中首次出现的地址
3.7 空字符串
#include <stdio.h>
#include <string.h>
int main(){
char str[10] = "";
char str2[] = "";
printf("%d\t%d\n",strlen(str),strlen(str2));
printf("%d\t%d\n",sizeof(str),sizeof(str2));
// char* str3; //错误,使用未初始化的char*,若指针定义时候无法确定初始值,使用NULL初始化指针
// printf("%s\n",str3);
}
0 0
10 1