【C语言学习记录】字符串
一、初识
二、字符串的结束标志’ \0 ’
字符串的结尾标志是0,如果没有结尾标志的情况我们在数组章节中已介绍过,现在我们介绍结尾标志后面的内容如何处理。
char strname[21];
memset(strname,0,sizeof(strname));
strcpy(strname,"abcdefghijk"); // 把abcdefghijk赋值给strname
strname[5]=0; // 强制把第6个元素赋值0
printf("%s",strname); // 输出的结果是abcde
以上代码输出的结果是abcde,但是,在内存中的值仍是abcde0ghijk,后面的ghijk成了内存中的垃圾值。
不要让字符串的内存中有垃圾值,容易产生意外的后果,我们将在后面的内容中演示,所以字符串的初始化不建议采用把第一个元素的值置为0的方式(strname[0]=0)。
三、sizeof和strlen的区别
四、动态开辟字符串
1、malloc
动态开辟内存空间;后记得释放所分配的内存空间;让指针指向NULL,防止悬挂指针;
2、realloc
扩容 函数原型void *realloc(void *ptr, size_t size)
3、free
释放,防止空间泄露,free之后让指针指向NULL,防止悬挂指针
4、memset
- 内存空间初始化
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
malloc:动态开辟内存空间;后记得释放所分配的内存空间;让指针指向NULL,防止悬挂指针
strcpy:拷贝 char *strcpy(char* dest, const char *src);//从src拷贝到dest去
realloc:扩容 void *realloc(void *ptr, size_t size);
memset: memset(p,'\0',12); //内存空间初始化
*/
int main()
{
char *p;//野指针
p = (char *)malloc(1);//p有了具体的内存指向
*p = 'c';
printf("%c\n",*p);
free(p);//动态开辟后重新指向,记得释放所分配的内存空间。不然存在内存泄露的风险
p = NULL; //free之后让指针指向NULL,防止悬挂指针
p = (char *)malloc(12); //开辟12字节的内存空间
if(p == NULL){ //通常养成习惯对malloc返回值做NULL判断,申请失败了
printf("malloc error\n");
exit(-1);
}
memset(p,'\0',12); //内存空间初始化
printf("扩容地址:%x\n",p);
int len =strlen("DT1213_STC8A8K64D4");
int newLen = len - 12 + 1;
p = realloc(p,newLen); //扩容
printf("扩容后地址:%x\n",p);
strcpy(p,"DT1213_STC8A8K64D4");//空间不够 越界 realloc扩容函数
puts(p);
puts("end");
return 0;
}
五、几种字符串常用的API
1、strcpy、strncpy 拷贝
- strcpy:拷贝 char strcpy(char dest, const char *src);//从src拷贝到dest去
- strncpy:拷贝 复制字符串的前n个字符
2、assert 断言
assert:断言 assert 的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向 stderr 打印一条出错信息,然后通过调用 abort 来终止程序运行
. 自己实现strcpy函数
char* myStrcpy(char*dest, char *src)
{
//assert(dest != NULL && src != NULL);//断言
if(dest == NULL || src == NULL){
return NULL;
}
char *bak = dest; //char备份地址bak保存目标地址dest
while( *src != '\0'){
*dest++ = *src++;
/*
*dest = *src;
dest++;
src++;
*/
}
*dest = '\0';
return bak;
}
char* myStrcpy2(char *des, char *src)
{
//assert(des != NULL && src != NULL);//断言
if(des == NULL || src == NULL){
return NULL;
}
char *bak = des;
while( (*des++ = *src++) != '\0');
*des = '\0';
return bak;
}
- 自己实现strncpy函数
char* myStrncpy(char *des, char *src, int count)
{
if(des == NULL || src == NULL){
return NULL;
}
char *bak = des;
while( *src != '\0' && count>0){
*des++ = *src++;
count--;
}
if(count > 0){
while(count > 0){
count--;
*des++ = '\0';
}
return des;
}
*des = '\0';
return bak;
}
3、strcat 拼接
函数原型:char strcat(char dest, const char src)
把src所指向的字符串(包括“\0”)复制到dest所指向的字符串后面(删除dest原来末尾的“\0”)。要保证dest足够长,以容纳被复制进来的src。*src中原有的字符不变。返回指向dest的指针。
- 自己实现strcat函数
char* myStrcat(char *des, char *src)
{
assert( des!=NULL && src!=NULL);//断言
char *bak = des;
while(*des != '\0'){ //while(*des)
des++;
}
while((*des++ = *src++) != '\0');
*des = '\0';
return bak;
}
char* myStrcat2(char *des, char *src)//指针偏移
{
char *bak = des;
strcpy(des + strlen(des), src);
return bak;
}
char* myStrcat3(char *des, char *src)
{
assert( des!=NULL && src!=NULL);
char *bak = des;
for( ; *des!='\0'; des++);
while((*des++ = *src++) != '\0');
*des = '\0';
return bak;
}
int main()
{
char str[128] = "DT1213_";
char *p = "STC8";
char *p2;
//strcat(str,p);
//puts(str);
p2 = myStrcat(str,p);
//p2 = myStrcat2(str,p);
//p2 = myStrcat3(str,p);
puts(p2);
return 0;
}
4、strcmp 比较
函数原型:int strcmp(const char *s1,const char *s2);
若str1=str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数
自己实现strcmp函数
计算字符ASCII值总和
int myStrcmp(char *str1, char *str2)
{
int ret = 0;
int n_str1 = 0; //计算ASCII值总和
int n_str2 = 0;
char *bakStr1 = str1;
char *bakStr2 = str2;
while( *str1 && *str2 && (*str1 == *str2)){
str1++;
str2++;
}
// if(*str1 || *str2){
// str1 = bakStr1;//指针回归,做运算
// str2 = bakStr2;
while(*str1){
n_str1 += *str1; //计算ASCII值总和
str1++;
}
while(*str2){
n_str2 += *str2;
str2++;
}
//}
ret = n_str1 - n_str2;
if(ret < 0){
ret = -1;
}
if(ret > 0){
ret = 1;
}
return ret;
}
int main()
{
char *p1 = "DTAB";
char *p2 = "DTBA";
int ret = strcmp(p1,p2);//-1 1 0 //返回-1
if(ret == 0){
puts("两个字符串相同");
}
printf("ret = %d\n",ret);
ret = myStrcmp(p1,p2);//-1 1 0 //返回0
if(ret == 0){
puts("两个字符串相同");
}
printf("ret = %d\n",ret);
return 0;
}

浙公网安备 33010602011771号