字符串

 

#include <stdio.h>
#include <stdlib.h>  //在各种编程语言中,字符串的地位都十分重要,C语言中并没有提供“字符串”这个特定类型,而是以特殊字符数组的形式来存储和处理字符串,
// 这种字符数组必须以空字符’\0’结尾,因此,也将这种特定字符数组称为C风格字符串,本节讨论字符串和字符串的一些处理函数。
// C风格字符串是字符数组的一种特例,这个“特”字体现在“以’\0’(空字符,null character)结尾
void main1(){
    char *strB[100] = {"China is great!"};  //字符串数组的正确定义方式,大括号可以省略
    char str[10]="calc";  //字符串常量,默认会在后面加 '\0'作为结束符,'\0'的ASCCI码为0,也就是 '\0'等价于ASCII码 0,'\0'不计入字符串的长度,
    // 注意ASCII码0不是数字0,数字0的ASCII码是48
    //char str[4] = {'c','a','l','c'};  //无法按照%s输出calc,会继续往后读取数据
     // char str[5] = {'c','a','l','c','\0'};  //按照%s正确输出calc,遇到'\0'就结束
     // char str[5] = {'c','a','l','c','0'};  //无法按照%s输出calc,'0'不是'\0',会继续往后读取数据
     // char str[10] = {'c','a','l','c','0'};  //按照%s输出calc0,'0'不是'\0',但是'0'后面的字符会默认赋值为'\0',遇到'\0'就结束
      //  char str[5] = {'c','a','l','c'};  //按照%s正确输出calc,str[4]没有指定值,会默认赋值为'\0',也是就是ASCII码 0,遇到'\0'就结束
    char *format = "str=%d, calc=%d\n";
    printf(format, sizeof(str), sizeof("calc"));  //str=10, calc=5  str[4]之后的都是默认为asci码的0,按照%c解析是'\0'

    //打印字符数组
    for (int i = 0; i < 10; ++i) {
        printf("str[%d]=[%d][%c]\n",i,str[i],str[i]);
    }

/*    str[0]=[99][c]
    str[1]=[97][a]
    str[2]=[108][l]
    str[3]=[99][c]
    str[4]=[0][ ]  默认赋值为ASCII码0,也是'\0',空字符,注意ASCII码0不是数字0,数字0的ASCII码是48
    str[5]=[0][ ]  默认赋值为0000000000000000二进制,按照%d和%c的解析方式不一样,结果因也会不一样
    str[6]=[0][ ]
    str[7]=[0][ ]
    str[8]=[0][ ]
    str[9]=[0][ ]*/
    printf("%s\n",str); //按照%s打印,遇到 '\0'才结束,没有就一直向前

    //system(str);

    int a[5] ={1,2,3};
    for (int j = 0; j < 5; ++j) {
        printf("[%d],[%c]",a[j],a[j]);  //[1],[╔][2],[╗][3],[╚][0],[ ][0],[ ]
    }
    //结论:默认赋值为0000000000000000二进制,按照%d和%c的解析方式不一样,结果因也会不一样
    // 整形数组会默认赋值为数字0,字符数组会默认赋值为'\0'
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main2(){
    char *str = "China is great!"; //把字符串常量的首地址赋值给指针str
    printf("str=%d,China is great!=%d\n", sizeof(str), sizeof("China is great!"));  //str=4,China is great!=16
    //str=4,China is great!=16  str是一个指针,固定4个字节
    printf("*Before:str =%c \n",*str);  //output:C
    //*str ='A';   //*str是字符常量C,无法给它赋值,常量只能读,不可以写
    printf("*After: str=%c\n",*str);  //output:C

    //对比下面的数组方式
    char strA[20] ="China is great!"; //字符数组是按照字符串常量一个一个依次给数组元素,数组strA是一个变量,可以赋值
    printf("str=%d,China is great!=%d\n", sizeof(strA), sizeof("China is great!"));  //str=20,China is great!=16
    //str=20,China is great!=16  str是一个数组
    printf("Before:*strA=%c",*strA);  //output:C
    *strA ='A';   //数组strA是一个变量,可以赋值
    printf("*After: strA=%c\n",*strA);  //output:A
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void main3(){
    char *str = "China is great!"; //把字符串常量的首地址赋值给指针str
    int i =0;  //统计字符串的长度
    while (*str){  //*str=='\0'
        putchar(*str);
        str++;
        i++;
    }
    printf("%d\n",i);  // 15  未统计'\0'
    printf("%d\n", sizeof("China is great!"));  //16

    //对比下面的数组方式
    char strA[20] ="China is great!"; //字符数组是按照字符串常量一个一个依次给数组元素,数组strA是一个变量,可以赋值
    //int *p = strA;  //错误,不能用int * 指针读取
    char *p =strA;
    while (p[0] != '\0'){ //p[0]总是p指针往后移动的第一个字符
        putchar(p[0]);
        p++;
    }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //二维数组存储字符串,每个一维数组都是一个字符串
void main4(){
    char str[5][6] ={ {"calc"},{"china"},{"great"}};
    // {"calc","china","great"} 里层的大括号可以省略
    for (int i = 0; i < 5; ++i) {
        printf("str[%d]=[%s]\n",i,str[i]);
    }
}
/*
str[0]=[calc]
str[1]=[china]
str[2]=[great]
str[3]=[]
str[4]=[]
 */

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// //字符指针和字符数组的初始化
void main5() {
    //字符数组
    printf("字符数组\n");
    char str[100]={0};
    scanf("%s",str);
    printf("\n%s",str);
    //字符指针
    printf("字符指针\n");
    //char *strP; //未初始化,是一段不可预知的内存地址
    //char *strP =NULL; //NULL的地址是0x000000,与系统访问冲突,
    //char *strP ="AAAAAAA";   "AAAAA"是常量,不能再次被赋值,常量不可以写
    char *strP =str;  //指针变量得指向一段可读可写的区域
    scanf("%s",strP);
    printf("%s",strP);
}
/*str是地址常量;strP是地址变量
strP接受键入字符串时,必须先开辟存储空间
 * 例   char  str[10];
       scanf(“%s”,str);    ()
而   char  *cp;
       scanf(“%s”,  cp);    (X)
 * 改为:  char   *cp,str[10];
           cp=str;
           scanf(“%s”,cp);
(1) 字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符串第1个字符的地址),决不是将字符串放到字符指针变量中。

(2)编译时为字符数组分配若干存储单元,以存放各元素的值,而对字符指针变量,只分配一个存储单元存储地址
scanf和printf
char ch[100];
scanf(“%s”,ch);     空格、制表符、换行为分隔符,作为输入结束符
printf(“%s”,ch);    输出后不会自动换行


gets和puts
char ch[100];
gets(ch);       回车为分隔符,作为输入结束符,会保留空格和制表符
puts(ch);       输出后会自动换行
*/

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/*//字符数组只有一个好处,就是可以整体是输入和输出,其他和数组一样,不能比较大小和四则运算,只能以字符元素来操作
头文件:#include <string.h>
strstr()函数用来检索子串在字符串中首次出现的位置,其原型为:
char *strstr( char *str, char * substr );
【参数说明】str为要检索的字符串,substr为要检索的子串。
【返回值】返回字符串str中第一次出现子串substr的地址;如果没有检索到子串,则返回NULL。
strcmp
int strcmp (const char* str1,const char* str2)
功能:字符串比较
        返回值:若参数s1和s2字符串相同则返回0,s1若大于s2则返回大于0的值,s1若小于s2则返回小于0的值
判断两个字符串大小1)ASII码 2)长度
        区分大小写比较的,如果希望不区分大小写进行字符串比较,可以使用stricmp函数
strncmp
 strchr

*/
//自定义函数实现strcmp
int myStrcmp(char *str1, char *str2){
    int i =0;
    while (str1[i] == str2[i] && str1[i] !='\0'){
        i++;
    }
    return str1[i] - str2[i];

}
void main6(){
    char str1[30] = "greatD";
    char str2[30] = "grec";
    if(myStrcmp(str1,str2) <0 ) {
        printf("str1 < str2");
    } else if(myStrcmp(str1,str2) > 0 ) {
        printf("str1 > str2");
    } else{
        printf("str1 = str2");
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//二级指针字符串
#include <string.h>
char str1[20] ="notepad";
char str2[20] ="calc";
void change(char **str){       //函数有副本机制,会新建一个二级指针变量str来存储main函数中p传过来str1的首地址
    printf("str in change: %p,%p\n",str,str2); //str in change: 00403008,0040301C

    *str = str2;  // *str就相当于一级指针 char * 用来改变main中p指针变量自己的首地址  *str=p=str2
    printf("change:%s,%p\n",*str,*str); //change:calc,0040301c
}
void main(){
    char *p =str1;
    printf("p in main: %p,%p\n",p,str1);  //p in main: 00403008,00403008
    change(&p);  //change把p的指向给改变,等价于p=str2
    printf("after change: %s,%p\n",p,p);  //after change: calc,0040301c
}

 

posted @ 2019-08-09 18:37  Coding_Changes_LIfe  阅读(144)  评论(0编辑  收藏  举报