(1.1.19)C语言之数目字、字符、字符串、数组、字符数组的关联和strcpy与memcpy的差别

(1.1.19)C语言之数字、字符、字符串、数组、字符数组的关联和strcpy与memcpy的差别

  • 概述
    • 数字和数字字符0
    • 数组不允许建立空数组a
    • 字符a和字符串a
    • 字符串的初始化
    • 字符数组的初始化
  • 字符串处理函数
    • strcat
    • strcpy函数
    • strncopystr1 str2 n
    • memcpy 函数void memcpyvoid dest void src unsigned int count

概述

Name 实例1 实例2 解析
数字 2 $1600
字符 ‘2’ $1600
字符串 “2” char str[ ]={‘I’,’ ‘,’a’,’m’,’ ‘,’h’,’a’,’p’,’p’,’y’,’\0’};
字符数组 char str[10]={ ‘I’,’ ‘,’a’,’m’,’ ‘,‘h’,’a’,’p’,’p’,’y’}

数字和数字字符:‘0’

(1.1.19)C语言之数目字、字符、字符串、数组、字符数组的关联和strcpy与memcpy的差别
数字2 存储为2
字符’2’ 存储为50
‘2’-2=50-2=48=’0’
‘d’-2=100-2=98=’b’
(1)数字2转数字字符’2’的方法:[+’0’]
2+’0’=2+48+=50=’2’
数字字符’2’转数字2的方法:[-‘0’]
‘2’-‘0’=50-48+=2

数组:不允许建立空数组a[]

声明:int a[]; 错误。
int a[]={1,2,3,4,5};
int a[10];

字符’a’和字符串”a”

虽然都只有一个字符,但在内存中的情况是不同的。
‘a’在内存中占一个字节,可表示为:
(1.1.19)C语言之数目字、字符、字符串、数组、字符数组的关联和strcpy与memcpy的差别
“a”在内存中占二个字节,可表示为:
(1.1.19)C语言之数目字、字符、字符串、数组、字符数组的关联和strcpy与memcpy的差别

字符串的初始化

方式 sizeof strlen 解析
char str[ ]={“I am happy”}; 11 10 字符数组存放字符串
char str[ ]=”I am happy”; 11 10 字符数组存放字符串
char str[ ]={‘I’,’ ‘,’a’,’m’,’ ‘,’h’,’a’,’p’,’p’,’y’,’\0’}; 11 10 字符数组存放字符串
char* str=”I am happy”; 11 10 字符指针指向字符串

PS:strlen()不计算空字符“\0”,但是sizeof()计算,因为空字符也占用一个字节
赋值方式不同:
(1) 字符指针:
正确:char* a; a=”I am happy”;
正确:char* a=”I am happy”;
(2)字符数组, 初始化可以一次性直接赋值,但是不能之后再一次性赋值,只能逐一赋值
错误:char str[11]; str=”I am happy”; 正确:char str[11]; str[0]=’I’; str[1]=’\0’;
正确:char str[11 ]=”I am happy”;

字符数组的初始化

方式 sizeof strlen 解析
char str[10]={ ‘I’,’ ‘,’a’,’m’,’ ‘,‘h’,’a’,’p’,’p’,’y’} 10 10
char str[2][3]={ “a”,”b”} 6 不能执行
char str[0][3]=”a”, str[1][3]=”b” 6 不能执行

字符串处理函数

strcat

char *strcat(char *str1,const char *2 );
char *strcat(char *strDestination,const char *strSource );
功能:函数将字符串str2 连接到str1的末端,并返回指针str1
注:连接前两个字符串的后面都有一个’ \0 ‘,连接时将字符串1后面的 ’ \0 ‘去掉,只在新串最后保留一个 ’ \0 ‘

strcpy函数

char *strcpy(char *str1,const char *2 );
char *strcpy(char *strDestination,const char *strSource );
功能:复制字符串strSource中的字符到字符串strDestination,包括空值结束符。返回值为指针strDestination。
注:1、“字符数组1”必须写成数组名形式,“字符串2”可以是字符数组名,也可以是一个字符串常量
2、复制时连同源字符串后面的 ’ \0 ’ 一起复制到数组1中,以’\0’为结束循环条件
3、不能用赋值语句直接将一个字符串常量或者字符数组直接赋给一个字符数组(同普通变量数组是一样的),而只能用strcpy函数处理。
4、可以用strcpy函数将字符串2中的前若干个字符复制到字符数组1中去。

#include<stdio.h>
#include<string.h>
void main()
{
char source[]="123456789";
char target[]="1234";
strcpy(target,source);
printf("%s",source);
}

因为target只占用5个字节空间,而source占用16字节大小,source和target被系统自动分配,在栈中是相邻的。strcpy内部实现相当与while(*target++=*source++);调用strcpy后会覆盖target部分内容
原来为1234\0123456789\0共15位的空间
转换后123456789\06789\0共15位空间

#include<stdio.h>
#include<string.h>
void main()
{
char target[]="1234";
char source[]="123456789";
strcpy(target,source);
printf("%s",source);
}

原来为123456789\01234\0共15位的空间
转换后123456789\0123456789\0共20位空间
可以正常输出结果,但是会抛出异常:访问越界,越过了目标串的长度

#include<stdio.h>
#include<string.h>
void main()
{
char target[]="1234";
char source[]={‘1’,‘2’,‘3’,‘4’,‘5’,‘6’};//注意是字符数组,没有‘\0’
strcpy(target,source);
printf("%s",source);
}

程序异常,strcpy找不到结束符

strncopy(str1, str2, n);

n为给定的值,语句将str2的前n个拷贝到str1中,值得注意的是一定会拷贝n个,不管str1是否有足够大的空间,n个必须拷贝完成语句才结束!切记!!如果你恰好有一个定义分配的空间在它后面的话,你就很肯能个因为str1的溢出而覆盖掉你在那定义的变量的值,当然你那恰好有定义的概率想当的小!

* memcpy 函数void *memcpy(void *dest, void *src, unsigned int count);*

用于 把资源内存(src所指向的内存区域) 拷贝到目标内存(dest所指向的内存区域);拷贝多少个?有一个size变量控制
拷贝的字节数;
char dest[1024] = “12345666”;//{0};
const char src[5] = “3333”;
那么拷贝的时候,如果用memcpy1(dest,src,sizeof(src));则printf(dest);出来是3333,也就是{‘3’,’3’,’3’,’3’,’\0}总共5个字节拷贝过去,3333\0666,也就是3333字符串
如果memcpy1(dest,src,4);则printf(dest);出来是33335666;因为上面的sizeof(src),包含’/0’,所以拷贝过去的字符串以’/0’结束,就只有3333,而如果传4个字符,’/0’是第五个字符,那就遇到dest[1024] 的’/0’结束,所以是33335666
字符串的’/0’问题一定要注意啊!!!