目录
一 概念:本质上 约等于 字符型数组
#include<stdio.h>
int main(){
//如何定义一个字符串
int data[] = {1,2,3,4,5};
char str1[] = {'h','e','l','l','o'};
char str2[] = "hello";
char *p_str = "hello";//常量:不可修改
str2[0] = 'H';
//*p_str = 'H';//会报错
/* 比较麻烦的传统输出方法
//概念不要混淆
int i = 0;
for(i=0;i<5;i++){
printf("%c",(*p_str + i));
}
putchar('\n');
for(i=0;i<5;i++){
printf("%c",*(p_str + i));
}
putchar('\n');
*/
printf("%s",p_str);//另一种输出方法
putchar('\n');
puts(p_str);
return 0;
}
/* 输出结果 */:
hijkl
hello
二 字符串内存
结尾包含一个字符串结束标志'\0'
char str4[] = "world";
也就相当于
char str4[] = {'w','o','r','l','d','\0'};
#include<string.h>
int data2[] = {9,8,7,6,5};
int len = sizeof(data2)/sizeof(int);
printf("sizeof = %d\n",len);//5
printf("sizeof = %d\n",sizeof(data2));
putchar('\n');
char str3[] = {'w','o','r','l','d'};
len = sizeof(str3)/sizeof(char);
printf("sizeof = %d\n",len);//5
printf("sizeof = %d\n",sizeof(str3));
putchar('\n');
char str4[] = "world";//结尾包含一个字符串结束标志'\0'
len = sizeof(str4)/sizeof(str4[0]);
printf("sizeof = %d\n",len);//6
printf("sizeof = %d\n",sizeof(str4));
printf("strlen = %d\n",strlen(str4));
char str5[128] = "world";//strlen只计算有效字符
printf("sizeof = %d\n",sizeof(str4));
printf("strlen = %d\n",strlen(str4));
putchar('\n');
char *p = "world";//strlen只计算有效字符
printf("sizeof = %d\n",sizeof(p));//p是一个指针,这里表示一个指针的大小
printf("sizeof = %d\n",sizeof(char *));//这里表示一个指针的大小
printf("sizeof = %d\n",sizeof(*p));//默认首个字符,这里就表示一个字符的大小
printf("sizeof = %d\n",sizeof(char));//表示一个字符的大小
printf("strlen = %d\n",strlen(p));
putchar('\n');
输出结果:
sizeof = 5
sizeof = 20
sizeof = 5
sizeof = 5
sizeof = 6
sizeof = 6
strlen = 5
sizeof = 128
strlen = 5
sizeof = 8
sizeof = 8
sizeof = 1
sizeof = 1
strlen = 5
sizeof和strlen:
可见字符串数组中可以直接用sizeof,但是这里要注意sizeof和strlen的区别
strlen:只计算有效字符的长度
sizeof(p):表示一个指针的内存大小,而不是字符串大小
三 更多API
1.malloc内存分配
可以避免野指针
malloc动态开辟字符串 栈 ==》堆
2.free
free(p);//释放内存,防止内存泄漏
后加
p = NULL;//防止悬挂指针(野指针的一种)
3.memset
memset(p,'\0',12);//都初始为‘\0’
4.strcpy和strncpy
strcpy:复制后者给前者
strncpy:设定复制的位数
5.realloc
realloc:给前者扩充后者(数字)大小
6.gets
gets(p); 《==》 scanf("%s",p);
gets本质上可以无限读取,容易造成内存泄漏
7.assert() 断言
现计算表达式,如果值为假(0),打印一条错误信息并停止运行
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
//malloc动态开辟字符串 栈 ==》堆
char *p;//野指针
p = (char *)malloc(1);//p有了具体内存指向
*p = 'c';
free(p);//释放内存,防止内存泄漏
p = NULL;//防止悬挂指针(野指针的一种)
//assert(p != NULL);
p = (char *)malloc(12);//修改指向
memset(p,'\0',12);//都初始为‘\0’
printf("扩容地址:%x\n",p);
int len = strlen("YuZhaoQun12138");
int newLen = len - 12 + 1;//确定扩容大小,+1放‘\0’
realloc(p,newLen);//扩容
printf("扩容后地址:%x\n",p);
//strcpy(p,"YuZhaoQun12138");//copy“后者”放进前者
strncpy(p,"YuZhaoQun1213888888888",14);
printf("%s\n",p);
gets(p);
//scanf("%s",p);
puts(p);
puts("ends");
return 0;
}
输出结果:
扩容地址:cc1410
扩容后地址:cc1410
YuZhaoQun12138
yzq12138
yzq12138
ends
8.strcat字符串拼接
把后者拼接在前者上,有返回值
9.strcmp字符串比较
为0则相同
#include<stdio.h>
#include<string.h>
int main(){
char str[16] = "hello ";
char *p = "world!";
char *p2 = "word!!";
strcat(str,p);
puts(str);
int ret = strcmp(p,p2);
if(ret == 0){
puts("they are same");
}else{
puts("they are different");
}
printf("%d\n",ret);
return 0;
}