字符串剖析

目录

一,字符串的一些混淆概念

1,字符串基本概念

2,字符串与字符数组

3,字符串长度

二,字符串的典型问题分析

1,snprintf函数

例1:比较S1和S2是否相等:

例2:字符串右移:

 


一,字符串的一些混淆概念

1,字符串基本概念

C语言中是没有字符串的概念的。

  • C语言中通过特殊字符数组来模拟字符串。

  • C语言中的字符串是以'\0'结尾的字符数组。

字符串是一种特殊的字面量,通过双引号引用。

  • 存储于程序的全局只读存储区。

  • 本质为字符数组,编译器自动在结尾加上'\0'字符。

2,字符串与字符数组

字符串本质为字符数组,两者之间的差别仅仅在于字符串在末尾处加上'\0'。

所以"hi!"和数组名一样,是一个地址。

char a1[] = a2[];
char aa[]={'h','i','!','\0'};
char bb[]="hi!";
char* str = "hi!";

以上2,3,4,均是字符串的定义。

1和2的区别:1是不成立的。因为不能直接用数组给数组赋值。但是2,3是成立的,因为可以用字符串给数组赋值。

注意:

  1. 字符串字面量本质是一个数组。

  2. 字符串字面量可以看成常量指针。

  3. 字符串字面量中的字符不能改变。因为存储在全局只读存储区里。

  4. 字符串字面量至少包含一个字符,那就是'\0',代表空字符。

当我们知道字符串本质为数组时,我们就可以为所欲为了:

char a = "abc"[0]; 
char b = *("abc" + 1);
char c = *"";

1行的意思是访问"abc"中的0号元素。

2行的意思是"abc"+1是指针运算,"abc"地址和0号元素地址一样,加一则指针指向1号元素'b',然后*取该值进行赋值。

3行的意思是""是空字符,*取该值'\0'赋值给c。因为'\0'的ASCⅡ码为0,所以c=0。

3,字符串长度

首先我们得注意的是字符串长度,指的是第一个'\0'出现前的字符长度。

函数strlen用于返回字符串的长度。

char s[] = "hi!";
printf("%d\n",strlen(s));
​
printf("%d\n",strlen("123"));

strlen和sizeof(name)/sizeof(type)的区别:

例如char a[ ] = "hello \0world"

strlen(a)就是等于7。

而sizeof(a)/sizeof(char)等于引号里面全部的字符个数 = 12。

扩展:字符串相关函数都依赖于结束符'\0'。


二,字符串的典型问题分析

1,snprintf函数

int snprintf(char* str, int n, const char*format,....);

简单来说:

  • str是要被写入字符串的。、

  • n则是为str能写入字符串的最大数目,超过就会被截断。

  • format则是要被写入str中的字符串。当format为一个字符串时,例如"hello"则就把该字符串写入str;如果format为一个字符串同时包含格式化信息时,例如"hello %s",则还需在后面加上%s对应的一个字符串。有多少个格式化信息,后面就要写多少个对应字符串。

 

#include <stdio.h>
#include <string.h>
​
int main()
{
    #define STR "Hello, \0World\0"
    
    char* src = STR;
    char buf[255] = {0};
    
    snprintf(buf, sizeof(buf), src);
    
    printf("strlen(STR) = %d\n", strlen(STR));
    printf("sizeof(STR) = %d\n", sizeof(STR));
    
    printf("strlen(src) = %d\n", strlen(src));
    printf("sizeof(src) = %d\n", sizeof(src));
    
    printf("strlen(buf) = %d\n", strlen(buf));
    printf("sizeof(buf) = %d\n", sizeof(buf));
    
    printf("src = %s\n", src);
    printf("buf = %s\n", buf);
    
    return 0;
}

例1:比较S1和S2是否相等:

#include <stdio.h>
#include <string.h>
​
int main()
{
    #define S1 "hello"
    #define S2 "hello"
    
    if( S1 == S2 )
    {
        printf("Equal\n");
    }
    else
    {
        printf("Non Equal\n");
    }
    
    if( strcmp(S1, S2) == 0 )
    {
        printf("Equal\n");
    }
    else
    {
        printf("Non Equal\n");
    }
    
    return 0;
}

第9行不相等。S1和S2做比较,本质可看做数组名的比较,那么数组名比较的是地址,而不是地址中保存的值。

第19行相等。strcmp(S1,S2);就是比较字符串内容是否相等。相等输出0,不相等输出1。

例2:字符串右移:

函数功能:要求字符串src循环右移n位,result为输出结果。

要求:效率最高。

#include <stdio.h>
#include <string.h>
​
void right_shift_r(const char* src, char* result, unsigned int n)
{
    const unsigned int LEN = strlen(src);
    int i = 0;
        
    for(i=0; i < LEN; i++)
    {
        result[(n + i) % LEN] = src[i];
    }
    
    result[LEN] = '\0';
}
​
int main()
{
    char result[255] = {0};
    
    right_shift_r("abcde", result, 2);
    
    printf("%s\n", result);
    
    right_shift_r("abcde", result, 5);
    
    printf("%s\n", result);
    
    right_shift_r("abcde", result, 8);
    
    printf("%s\n", result);
    
    return 0;
}

Guess you like

Origin blog.csdn.net/m0_58702068/article/details/118773316