zoukankan      html  css  js  c++  java
  • 【C】字符串,字符和字节(C与指针第9章)

    C语言没有一种显式的数据类型是字符串的。

    C语言存储字符串:字符串常量(不能改动)。字符数组或动态分配的内存(能够改动)


    ****************************************************

    9.1 字符串基础

    字符串概念:字符串是以一个位模式为全0的NUL字节结尾的0个或多个字符

    NUL字节是终止符,字符串的长度不包括NUL字节

    头文件string.h包括了使用字符串函数所需的原型和声明(能够在linux中查看,有非常多函数声明)。


    ****************************************************

    9.2 字符串长度

    size_t是一个无符号整数类型。定义与stddef.h头文件

    做算术运算的时候无符号整数可能导致不可预料的结果(想想,见9.2)


    ****************************************************

    9.3 不受限制的字符串函数

    ——》复制字符串 strcpy函数:  char *strcpy( char *dst, char const *src);

    Note:

    1.复制字符串也会复制NUL字节;

    2.假设dst目标字符数组空间不足以容纳须要复制的字符串。strcpy将侵占数组后面的部分内存空间(由于strcpy无法推断目标字符数组的长度,这也是”不受限制“的含义吧)

    ——》连接字符串 strcat函数: char *strcat( char *dst, char const *src );

    Note:

    1.这个函数找到dst的末尾(NUL字节吗),把src字符串的一份拷贝加入到这个位置

    2.这个函数也有strcpy的特点,假设dst空间不足以容纳须要复制的字符串了。则也将侵占数组后面的部分空间

    ——》字符串比較 strcmp: int strcmp(char const *s1, char const *s2);

    Note:

    1.这个函数的结果符合“字典比較”


    ****************************************************

    9.4 长度指定了限制的字符串函数

    上面没有受限的函数是以寻找字符串结尾的NUL字节来推断长度。这里的函数指定进行复制或比較的字符数

    ——》strncpy函数:char *strncpy( char *dst, char const *src, size_t len );

    Note:

    1.把源字符串src的指定数目字符拷贝到目标数组dst;假设src没有len个字符,则会用NUL字节填充到dst

    2.假设是strlen(src)大于len。那么仅仅有len个字符会进行复制。!可是,它的结果将不会以NUL字节结尾。

    (也就是说,strncpy调用的结果可能不是一个字符串哦)

    ——》strncat函数:char *strncat( char *dst, char const *src, size_t len);

    Note:

    1.strncat在连接完后,会自己主动在结果后加上一个NUL(因此这还是比較安全的,不会由于没有NUL而在其它函数中出现故障),比例如以下程序

    #include <string.h>
    #include <stdio.h>
    
    int main()
    {
    	char *src = "world";
    	char dst[7] = "hello";
    	strncat(dst, src, 5);
    	printf("%s", dst);
    
    	return 0;
    }

    由于dst容量(7)不够装下helloworld(11),因此strncat会侵占几个dst后面的字节。可是在侵占完后。strncat还是会加上一个NUL字节。因此既有不安全的一面(侵占兴许字节)也有安全的一面(自己主动加NUL字节)

    2.在src的长度不够len时,它不会用NUL字节继续填充dst

    *************************下面是一些相关的辨析

    #include <string.h>
    #include <stdio.h>
    
    int main()
    {
    	
    	char *src = "world";
    	printf("length of src is %d
    ", sizeof(src));
    	printf("length of src is %d
    ", strlen(src));
    	
    	char dst[7] = "hello";
    	int mat[100];
    	strncat(dst, src, 9);
    	printf("%s
    ", dst);
    
    	printf("length of dst is %d
    ", sizeof(dst));
    	printf("length of src is %d
    ", sizeof(src));
    	printf("length of src is %d
    ", strlen(src));
    	printf("length of mat is %d
    ", sizeof(mat));
    
    	return 0;
    }
    执行结果为



    这说明了几点:

    1.对于数组名来说,通常是作为指针。可是在sizeof(数组名)中,是求取了数组占用的“字节”数;

    2.在strncat后,输出helloworld后。对dst数组求字节数却还是7. 说明数组长度是被记录下来的。不会变化了。可是往后仅仅要用%s格式输出dst,都会输出helloworld。由于在后面都增加了'';

    3.全然不解!

    为什么在開始strlen(src)还有5,可是在调用了strncat之后strlen(src)就仅仅有1了?求解答~


    再看下面的程序

    #include <string.h>
    #include <stdio.h>
    
    int main()
    {
    	//1
            *src = "hello";
    	printf("length of src is %d
    ", sizeof(src));
    													
    
    	// 2		
    	printf("length of 'hello' is %d
    ", sizeof("hello"));
    	
    	// 3
    	char haha[] = "hello";
    	printf("length of haha is %d
    ", sizeof(haha));
    	
    
    	return 0;
    }


    执行结果为


    这说明了下面几点:

    1. 行1&2结合,我的分析是。在1中src在可重定位目标文件里是一个存在于符号表中的标识符,是一个指针变量,以常量字符串“hello”的起始地址初始化(执行时);而在2中“hello”是一个常量字符串。在执行前已经存放好,放在可重定位目标文件(编译汇编之后,链接之前产生的文件).rodata segment中(?不正确耶,用objdump查看了,行1中的“hello”确实存放在rodata段中,可是sizeof(“hello”)中的“hello”没有放在rodata中,由于若删去第1行,则rodata中没有hello了,例如以下图是删去了第1行两句话)


    2.结合2&3分析,说明字符数组包括了''


  • 相关阅读:
    [大数据相关] Hive中的全排序:order by,sort by, distribute by
    [mysql] Mysql数据分组GROUP BY 和HAVING,与WHERE组合使用
    【hadoop环境问题】namenode无法启动问题解决
    【java】Java.math.BigDecimal.subtract()方法实例
    利用 force index优化sql语句性能
    navicat连接远程数据库报错'client does not support authentication protocol requested by server consider ...'解决方案
    spark SQL学习(数据源之parquet)
    spark SQL学习(load和save操作)
    spark学习(RDD案例实战)
    spark学习12(Wordcount程序之spark-shell)
  • 原文地址:https://www.cnblogs.com/clnchanpin/p/6857268.html
Copyright © 2011-2022 走看看