程序员面试宝典 C14字符串 14.2 字符串数组和strcpy

来源:互联网 发布:seo推广是什么 编辑:程序博客网 时间:2024/04/30 19:31

面试例题2

原题

下面的程序会出现何种问题?

#include<isotream>#include<stdio.h>int main(void){    char s[] = "123456789";    char d[] = "123";    strcpy(d,s);    printf("%s, \n%s",  d, s);    return 0;}

书上给出答案是

输出结果为 123456789,56789

给的解释是

分配的内存地址是连续内存, 源字符串被覆盖。

补充

出现何种问题?

还要再加一个:
没有#include<string.h>或者#include<cstring.h>,或者自定义一个strcpy(),编译都通不过。

为什么连续内存会被覆盖

  1. 数组在内存中是连续存储的
  2. string.h 中的函数都是对字符串操作, C语言字符串都是以'\0'为截止符的

对于本地,执行strcpy()前后,内存大致如下:

这里写图片描述

  1. 先定义局部变量s[],再定义d[]。
  2. strcpy 将源字符串逐个字符复制到目标字符串,直到遇到’\0’,(‘\0’也要复制)
  3. 此时strlen(d) == 10,strlen(s) == 6, d和s公用了6个字符。

为什么先定义s[],后定义d[]

按照C语言的直观理解,就是因为char s[] = "123456789";char d[] = "123"; 前面吗?

GCC

实际上,用gcc测试时发现 无论这两句先后顺序如何,d的地址总是比s的低,看起来,gcc是根据字符串长度来分配内存。

#include<stdio.h>#include<string.h>int main(){        {                char sp[] = "123";                char ln[] = "123456789";                printf("short in the front: %u\n", &sp[0]);                printf("long  in the back : %u\n", &ln[0]);        }        {                char lp[] = "123456789";                char sn[] = "123";                printf("lont in the front: %u\n", &lp[0]);                printf("short in the back: %u\n", &sn[0]);        }    return 0;}

GCC环境下

上图中的main函数中两对大括号,使得两次实验的环境相对隔离;没有它们,四个数组将在同一作用域内,那样的话,内存中就是两个短的数组在前,两个长的在后。

GCC环境:

gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609

VC

至于MSVC,结果如图,它成功地绕过了。又爱又恨。。。。。。

#include "stdafx.h"#include<string.h>int main(){    char s[] = "123456789";    char d[] = "123";    printf("s:%u\n", (unsigned int)&s[0]);    printf("d:%u\n", (unsigned int)&d[0]);    strcpy(d, s);    printf("%s,\n%s\n", d, s);    printf("s:%u\n", (unsigned int)&s[0]);    printf("d:%u\n", (unsigned int)&d[0]);    getchar();    return 0;}

VC环境下

VC环境:

Microsoft Visual Studio Community 2017
版本 15.2 (26430.6) Release

Visual C++ 2017 00369-60000-00001-AA422
Microsoft Visual C++ 2017

阅读全文
0 0
原创粉丝点击