指针与字符串

Tutorial: C与汇编 Category: C语言 Published: 2026-04-07 13:58:26 Views: 20 Likes: 0 Comments: 0
1. 字符串集中表示方式及区别
#include <stdio.h>

int main()
{
    char str1[5] = {'A', 'B', 'C', 'D', 'E'};
    printf("%s\n", str1);

    char str2[6] = {'A', 'B', 'C', 'D', 'E', 0}; // 0 可以改为 '\0' 这种写法
    printf("%s\n", str2);

    char str3[] = "ABCDE";
    printf("%s\n", str3);

    char *str4 = "ABCDE";
    printf("%s\n", str4);

    return 0;
}

5:        char str1[5] = {'A', 'B', 'C', 'D', 'E'};    // 会打印多余的东西,编译器一直打印,直到找到 0
0040D448   mov         byte ptr [ebp-8],41h
0040D44C   mov         byte ptr [ebp-7],42h
0040D450   mov         byte ptr [ebp-6],43h
0040D454   mov         byte ptr [ebp-5],44h
0040D458   mov         byte ptr [ebp-4],45h
6:        printf("%s\n", str1);
0040D45C   lea         eax,[ebp-8]
0040D45F   push        eax
0040D460   push        offset string "%s\n" (00422024)
0040D465   call        printf (0040d750)
0040D46A   add         esp,8
7:
8:        char str2[6] = {'A', 'B', 'C', 'D', 'E', 0}; // 能正确打印,末尾有0
0040D46D   mov         byte ptr [ebp-10h],41h
0040D471   mov         byte ptr [ebp-0Fh],42h
0040D475   mov         byte ptr [ebp-0Eh],43h
0040D479   mov         byte ptr [ebp-0Dh],44h
0040D47D   mov         byte ptr [ebp-0Ch],45h
0040D481   mov         byte ptr [ebp-0Bh],0
9:        printf("%s\n", str2);
0040D485   lea         ecx,[ebp-10h]
0040D488   push        ecx
0040D489   push        offset string "%s\n" (00422024)
0040D48E   call        printf (0040d750)
0040D493   add         esp,8
10:
11:       char str3[] = "ABCDE";
0040D496   mov         edx,dword ptr [string "ABCDE" (0042201c)] // 先把字符串放到常量区, 常量区是没法改的
0040D49C   mov         dword ptr [ebp-18h],edx                   // 拷贝到数组中(就支持修改了) edx,是4字节寄存器,还差一个字节
0040D49F   mov         ax,[string "ABCDE"+4 (00422020)]          // 复制 'E' + 一个 0 到ax中
0040D4A5   mov         word ptr [ebp-14h],ax                     // 放在数组里,自动补0
12:       printf("%s\n", str3);
0040D4A9   lea         ecx,[ebp-18h]
0040D4AC   push        ecx
0040D4AD   push        offset string "%s\n" (00422024)
0040D4B2   call        printf (0040d750)
0040D4B7   add         esp,8
13:
14:       char *str4 = "ABCDE";
0040D4BA   mov         dword ptr [ebp-1Ch],offset string "ABCDE" (0042201c) // 放到常量区,没法改
15:       printf("%s\n", str4);
0040D4C1   mov         edx,dword ptr [ebp-1Ch]
0040D4C4   push        edx
0040D4C5   push        offset string "%s\n" (00422024)
0040D4CA   call        printf (0040d750)
0040D4CF   add         esp,8
2. 字符串常用方法
- size_t strlen(const char* s)
    返回字符串s的长度,不包括终止字符'\0'。

- char* strcpy(char* dest, const char* src)
    将字符串src复制到dest所指向的数组,包含终止字符'\0',返回dest。

- char* strncpy(char* dest, const char* src, size_t n)
    将字符串src的前n个字符复制到dest所指向的数组,如果src的长度小于n,则在dest之后的剩余部分用'\0'填充。

- char* strcat(char* dest, const char* src)
    将字符串src连接到字符串dest的末尾,覆盖dest中的终止字符'\0',并在新形成的字符串末尾添加一个终止字符'\0'。

- char* strncat(char* dest, const char* src, size_t n)
    类似strcat,但是最多只会添加n个字符,之后再添加终止字符'\0'。

- int strcmp(const char* s1, const char* s2)
    比较两个字符串s1和s2。如果s1的字典顺序低于s2,返回负数;如果s1的字典顺序高于s2,返回正数;如果两者相等,返回0。

- int strncmp(const char* s1, const char* s2, size_t n)
    类似strcmp,但是比较从字符串str1和str2开头的最多n个字符。

- char* strchr(const char* s, int c)
    在字符串s中查找首个出现的字符c(一个无符号字符),返回指向该字符的指针,如果找不到,返回NULL。

- char* strrchr(const char* s, int c)
    在字符串s中查找最后一次出现的字符c(一个无符号字符),返回一个指向该字符的指针,如果找不到,返回NULL。

- char* strstr(const char* haystack, const char* needle)
    在字符串haystack中查找子串needle的首次出现,返回一个指向开始位置的指针,如果找不到,返回NULL。

- char* strtok(char* str, const char* delim)
    分解字符串str为一系列的标记字符串。delim为分隔符字符串,此函数返回在str中最后被找到的分隔符后的一个指针,如果未找到,则返回NULL。

- size_t strspn(const char* s, const char* accept)
    计算字符串s中连续的字符在accept内的最长子序列的长度。

- size_t strcspn(const char* s, const char* reject)
    计算字符串s中连续的字符不在字符串reject内的最长子序列的长度。

- char* strpbrk(const char* s, const char* accept)
    搜索字符串s中首个出现在字符串accept内的字符位置,返回一个指向找到的字符的指针,如果未找到,返回NULL。

- char* strerror(int errnum)
    返回一个描述错误代码errnum的字符串,通常用于解释errno的值。

- void* memset(void* s, int c, size_t n)
    将s所指向的内存区域的前n个字节设置为字符c。

- void* memcpy(void* dest, const void* src, size_t n)
    从src复制n个字节到dest,返回dest。

- void* memmove(void* dest, const void* src, size_t n)
    将src指向的内存区域的前n个字节移动到dest指向的内存区域,这个函数对重叠的内存区域是安全的,意思是即使src和dest的内存区域有重叠,这个函数也能够正确地处理复制(移动)。
    与memcpy不同,memcpy在源和目标区域重叠时的行为是未定义的。
    memmove之所以能够正确处理重叠区域,是因为它会先确定重叠的方向,然后从src的开头或者末尾开始复制,以避免在复制过程中覆盖还未被复制的数据。
    memmove函数的返回值是指向目标内存区域dest的指针。
- void memchr(const void s, int c, size_t n)**
    在s指向的内存块的前n个字节中搜索第一次出现的字符c(一个无符号字符),返回一个指向被找到字符的指针,如果未找到,则返回NULL。

- int memcmp(const void s1, const void s2, size_t n)**
    比较内存块s1和s2的前n个字节。如果s1小于s2,返回负数;如果s1大于s2,返回正数;如果二者相同,返回0。

- void memmove(void dest, const void* src, size_t n)**
    与memcpy类似,但是在复制过程中会考虑到源和目标内存区域重叠的情况。

- char strdup(const char s)**
    复制字符串s,分配足够的堆内存,并返回指向这个新分配内存的指针。注意,使用完毕后应该调用free来释放它。

- char strcoll(const char s1, const char* s2)**
    比较两个字符串s1和s2,但是是根据程序的当前区域设置来决定比较结果的。

- char strncoll(const char s1, const char* s2, size_t n)**
    与strcoll类似,但比较的是字符串s1和s2的前n个字符。

- size_t strxfrm(char dest, const char src, size_t n)**
    根据程序的区域设置来转换字符串src,此转换假设足以在任何情况下保证顺序,并将结果存储在dest中,最多存储n个字符。