C语言基础-指针与字符串19

来源:互联网 发布:软件开发的学校 编辑:程序博客网 时间:2024/05/18 05:29

 1. 指针和字符变量.

 

    char ch = 'a';

 

    char* p1 = &ch;

 

    *p1 = 'b';

 

    printf("ch = %c\n",ch);

 

 

 2. 指针与字符数组.

 

    char chs[] = {'a','b','c','d'};

 

    char* p1 = chs; //p1指向指向了chs数组的第0个元素.

 

    *p1 = 'x';

 

 

    也可以使用指针来遍历数组中的每一个元素;

 

    *(p1+i);

    *(chs+i);

    *(p1++);


    只有当我们直接初始化1个字符串数据给1个字符数组的时候,才会自动加1'\0'.

    char name[] = "jack";

 

 3. 字符串数据在C语言中的存储.

 

    1).使用字符数组来存储.

 

        将字符串数据的每一个字符,存储到字符数组中,并追加1'\0'代表存储结束,

 

        char name[5] = {'j','a','c','k','\0'};

        char name[] = {'j','a','c','k','\0'};

 

        char name[] = {"jack"};只有直接给字符串数组初始化1个串的时候,才会自动追加1'\0'.前提是字符数组的长度足够的情况下.

 

        char name[] = "jack";

 

 

    2).使用字符指针来存储字符串数据.

 

        直接将1个字符串数据初始化1个字符指针.

 

        char* name = "jack";

 

        虽然我们不知道这个的原理.但是有1点值得肯定.

        绝对不是将"jack"存储到指针变量name.

        name1个指针变量.只能存储地址.

     

 4. 存储字符串的两种方式的区别.

 

    1).使用字符数组来存储:将字符串数据的每1个字符存储到字符数组的元素中,追加1'\0'表示结束.

        char name[] = "jack";

    2).使用字符指针来存储:直接为字符指针初始化1个字符串数据.

        char *name = "jack";

        

    ------------

    1).当他们都是局部变量的时候.

         char name1[] = "jack";

         char *name2 = "rose";

 

        a. name1字符数组.是申请在栈区.字符串的每一个字符存储在这个字符数组的每1个元数中.

        b. name21个局部的指针变量,name2这个指针变量是声明在栈区的.

           这个时候, 字符串数据是存储在常量区中的.

           字符串数据就是以字符数组的形式存储在常量区.

           name2指针变量中.存储的是"rose"这个字符串在常量区的地址.


    2).当他们作为全局变量的时候.

         char name1[] = "jack";

         char* name2 = "rose";

 

         a. name1字符数组是存储在常量区的.字符串的1个字符是存储在这个数组中的每一个元素中.

         b. name2指针也是存储在常量区的.字符串也是以字符数组的形式存储在常量区.

            name2指针中存储的是 "rose"这个字符串在常量区的地址.


    这两种方式的区别.

    在内存中存储的结构是不同的.

    a. 以字符数组存储:无论如何是1个字符数组.然后字符串的每一个字符存储在数组的元素之中.  

    b. 以字符指针存储:无论如何首先有1个字符指针变量.字符串数据是以字符数组的形式存储在常量区的.

 

    -----------------

    

    1).以字符数组存储的字符串数据,可以修改字符数组的元素.

 

        以字符数组的形式存储字符串数据,不管是全局的还是局部的,都可以使用下标去修改字符数组中的每一个元素.

 

    2).以字符指针的形式存储字符串数据.这个时候字符指针指向的字符串数据是无法修改的.

 

        以字符指针的形式存储字符串数据,不管是全局的还是局部的,都不能通过指针去修改指向的字符串数据.

 

    可变与不可变.

 

5 字符串的恒定性.

 

    大前提:是以字符指针形式存储的字符串.

 

    1).当我们以字符指针的形式存储字符串的时候,无论如何字符串数据是存储在常量区的.

        并且一旦存储到常量区中去.这个字符串数据就无法更改.

 

    2).当我们以字符指针的形式要将字符串数据存储到常量区的时候,并不是直接将字符串存储到常量区.

        而是先检查常量区中是否有相同内容的字符串.

        如果有,直接将这个字符串的地址拿过来返回.

        如果没有,才会将这个字符串数据存储在常量区.

 

    3).当我们重新为字符指针初始化1个字符串的时候 

        并不是修改原来的字符串.而是重新的创建了1个字符串.

        把这个新的字符串的地址赋值给它.

 

    4).最容易蒙圈的地方.

        a.  char *name = "jack";

            name = "rose"; 这样是可以的.但是

                            不是把"jack"改成了"rose"而是重新创建了1"rose"

                            "rose"地址赋值给name

 

        b.  char name[] = "jack";

            name = "rose";这样是不行的. name是数组名代表数组的地址.不能为数组名赋值.

 

            name[0] = 'r';

            name[1] = 'o';

            name[2] = 's';

            name[3] = 'e';

            name[4] = '\0'  这么做是可以的直接修改数组的元素

6 字符串函数补充

 

   1. fputs();  f --> File

 

    作用:将字符串数据 输出到 指定的流中.

         : 标准输出流->控制台.

             文件流 -->磁盘上的文件.


    使用格式:

    fputs(要输出的字符串,指定的流);

 

    1).要使用fputs函数将字符串数据输出到标准输出流.

        标准输出流:控制台. stdout

 

    2).将字符串存储到文件中.

 

        a. 要先声明1个文件指针.指向磁盘上的文件.

           fopen函数可以创建1个指向文件的指针.

           fopen函数的两个参数:

           1个参数:文件的路径,代表创建的指针就指向这个文件.

           2个参数:操作文件的模式. 你要对这个文件做什么操作.必须要告诉他.

                    "w"  --> write  代表你要向这个文件写入内容.

                    "r"  --> read   代表你从这个文件中读取数据.

                    "a"  --> apped  追加 代表你向这个文件中追加数据

 

           当操作模式是"w"的时候,如果文件不存在.就会创建这个文件.

                              如果文件存在. 就会将原来的文件替换掉.

 

           当操作模式是"a"的时候.如果文件存在,则追加.如果不存在就创建这个文件.


        b. 使用fputs函数将字符串写入到指定的文件流中.

 

            fputs(字符串,文件指针);

 

        c. 写完之后,一定要记得使用fclose()函数将这个文件关闭.

 

 2. fgets()函数.

 

    作用:从指定的流中读取字符串.

         这个流可以是我们的标准输入流-->控制台.

             也可以是我们的文件流.


    1).使用fgets函数从标准输入流中读取数据.

        使用fgets函数从控制台接收用户输入字符串.


        前面学习的scanf函数gets函数也可以实现这个功能.


        scanf的缺点

        a. 不安全.

        b. 输入的空格会被认为结束.


        gets函数的缺点.

        a. 不安全.

 

        fgets函数的优点

        a. 安全

        b. 空格也会一并接收.

 

        语法:  fgets(要将字符串存储到哪1个数组中,最多接收多少个长度的字符串,指定流);

        2个参数:我们写1n那么函数最多就接收n-1个长度的字符串.

                  这个参数一般情况下和第1个参数数组的长度一致.

        stdin: 代表标准输入流.也就是键盘流 控制台输入.

        为什么是安全的?

        a. 如果我们输入的字符串的长度大于等于了2个参数n.只会接收前面的n-1.然后最后1个自动是'\0'.

           这样,就不会崩了.

        b. 如果我们输入的字符串的长度刚好等于n-1那就是最完美的.

        c. 如果我们输入的字符串的长度小于了n-1.那么就会将我们最后输入的换行字符'\n'一并的接收.

           然后后面才是'\0'结束符.


        解决方案:输入完毕之后,判断字符数组中存储的字符串最后1个是不是'\n'

                 如果是'\n'那么就将其替换为'\0'.

 

    2).使用fgets函数从文件流中读取数据:

        就是读取磁盘上文件的内容.

 

        a. 先创建1个文件指针.

             //1. 创建1个读取文件的文件流.

             FILE* pFile = fopen("/Users/Itcast/Desktop/abc.txt", "r");

 

        b. 准备1个字符数组.准备存储读取到的字符串数据.

            

             char content[50];

 

        c. 使用fgets函数从指定的文件流中读取.

 

            fgets(content, 50, pFile);


        d. 读取成功:

            printf("读取的内容是: %s\n",content);


        e. 关闭文件流

            fclose(pFile);

 


原创粉丝点击