c入门第十三篇——字符数组放不下一个女生的名字

师弟:“师兄,我最近在学习字符串的操作,遇到一个奇怪的现象,你帮我看看。”
我:“好啊,你描述一下现象呢?”
师弟:“我给一个字符串赋值,结果影响了另外一个整型的数值。程序简化如下。”

#include 
#include 

int main()
{
    long long a = 2;
    char name[8];
    strcpy(name, "chengxia");
    printf("name: %s\n", name);
    printf("a: %lld\n", a);

    return 0;
}

我:“你这是字符串溢出了。”
师弟:“溢出了?我定义的数组大小为8,赋值的字符串长度也为8,怎么会溢出呢?”
我:“在C语言中,字符串以空字符 ‘\0’ 结尾,所以它尾部还有一个隐形的字符。”
Linux系统可以通过man strcpy来看一下函数帮助,帮助中说明了会一并将’\0’进行拷贝,故溢出了。

DESCRIPTION
The strcpy() function copies the string pointed to by src, including the terminating null byte (‘\0’), to the buffer pointed to by dest. The strings may not overlap, and the
destination string dest must be large enough to receive the copy. Beware of buffer overruns! (See BUGS.)

然后可以通过打印地址信息,也可以发现地址的确溢出了。

#include 
#include 

int main()
{
    long long a = 2;
    char name[8];
    strcpy(name, "chengxia");
    printf("name: %s\n", name);
    printf("a: %lld\n", a);
    printf("%p %p %p\n", &name, &name[7], &a);//打印地址信息

    return 0;
}

字符串

早之前也说到,在C语言中,没有直接支持字符串类型,字符串是字符的序列,以空字符 ‘\0’ 结尾。这个空字符不是数字0,而是ASCII码中值为0的字符,用于标记字符串的结束。通常是通过字符数组或指向字符的指针来操作字符串。
字符串的几种表达形式如下:

char str[6] = {'h', 'e', 'l', 'l', 'o', '\0'};
char str[] = "hello"; //字符数组
char *str = "hello"; //字符指针
#define HELLO "hello" //宏定义

在使用字符串的时候,要时刻牢记字符串结束符’\0’。
C语言的标准库()提供了一些函数来操作字符串,在Linux系统中,可以通过man来看函数的用法。

函数 功能
strcpy(dst, src)/strncpy(dst, src, n) 字符串拷贝
strcat(dst, src)/strncat(dst, src, n) 字符串拼接
strlen(s) 字符串长度
strcmp(s1, s2)/strcnmp(s1, s2, n) 字符串比较
strchr(s, c)/strrchr(s, c) c在s中第一次(最后一次)出现的位置
strstr(s1, s2)/strcasestr(s1, s2) 子串判断

在做字符串拷贝的时候,一般首选strncpy,防止缓冲区溢出。

strcpy 和 memcpy比较
这两个函数都能进行字符串的copy,但是memcpy又不仅仅局限于字符串的copy,memcpy功能更广,主要是进行内存字节级拷贝。
strcpy会默认赋值’\0’,但是memcpy不会。
用这2个函数实现字符串的拷贝,示例如下:

#include 
#include 

void name_strcpy(char *s)
{
    char name[16];
    strcpy(name, s);
    printf("name: %s\n", name);
}

void name_memcpy(char *s)
{
    char name[16];
    int len = strlen(s);
    memcpy(name, s, len);
    name[len] = '\0';
    printf("name: %s\n", name);
}

int main()
{
    char name[] = "chengxia";
    name_strcpy(name);
    name_memcpy(name);
    return 0;
}

题外

我:“chengxia是谁?”
师弟哈哈一笑:“就是那个给我出题的女生。”

ascii表: https://baike.baidu.com/item/ASCII/309296?fr=ge_ala

你可能感兴趣的:(c语言入门,c语言,开发语言,程序人生,算法,数据结构)