字符串
特点:
形式上"hello"
存储上"hello"---本质上是按照字符数组的特点存储
字符串 就是一串字符,最后会有一个'\0'作为结束标志 这是系统自动加上去的 它的ASCII码为0,用它作为字符串结束标志不会产生附加的操作或增加有效字符。
字符数组
用字符串初始化
//赋值
//通过表达式给值
for (i = 0; i < n; ++i)
{
s[i] = 'a'+i;
}
//通过输入键盘给值
for (i = 0; i < n; ++i)
{
//scanf("%c",&s[i]);
s[i] = getchar();
}
gets()
功能:给字符数组中,输入一个"字符串"
char *gets(char s[]) // 传一个字符数组的数组名
参数:s 表示需要传的是一个字符数组的名字
返回值: 表示存放字符串的那块空间的地址
注意 这个函数是危险的,使用时会出现警告,不推荐使用。
puts()
功能:将字符串输出,它会默认输出一个'\n'
strlen()
字符串的长度指的是'\0'前面字符的个数
//字符串复制
因为字符数组不能整体赋值
while()
{
//逐个字符1操作 复制过去
}
//为了让s2是字符串
s[i] = '\0'; //让最终成为字符串
puts(s2);
strcpy //字符串拷贝函数
char *strcpy(char *dest, const char *src); //将src中字符串拷贝到dest中
用法:
strcpy(dest,src); //dest是一个字符数组的数组名
//src 可以是字符数组数组名 也可以是字符串常量
字符串赋值要用 strcpy(mid,s[i]); 不能用char mid = s[i];
strcat
//它不会判断空间是否够用的情况 会出现栈奔溃的情况
char *strcat(char *dest, const char *src)
功能:
将src中的字符串拼接到dest中
参数:
@dest 拼接的目的字符串
@src 拼接的源字符串
strcmp
int strcmp(const char *s1,const char *s2);
功能:
比较s1和s2的字符串大小
字符串的比较:
规则:字符串比较的规则与其他语言中的规则相同,即对两个字符串自左至右逐个字符相
比(按 ASCII 码值大小比较),直到出现不同的字符或遇到'\0' 为止
比较的结果由函数值带回。
(1) 如果字符串 l= 字符串 2, 则函数值为 0
(2) 如果字符串 l> 字符串 2, 则函数值为一个正整数。
(3) 如果字符串 1< 字符串 2,则函数值为一个负整数。
该函数值就是最后一个不同字符间的ASCII码值的差
二维数组
语法:
类型说明符 数组名 [常量表达式][常量表达式]
类型说明符 -- 表示数组中要存储的数据的类型
数组名---- 代表 1数据类型 2首元素的地址即基地址
eg: int a[3][4];
理解二维数组:
int a[行数][列数];
int a [3][4]; //形式上定义的是一个 三行四列 的总共包含12个int常量的二维数组,注意是形式上
sizeof(a[0]);//此时一列有四个int型元素 为4*4=16
sizeof(a[3][4]);// 4*12=48
sizeof(a[0][0]);// 4
计算机对数据的存储是线性的,不存在真正意义上的二维;二维数组采用这样的定义方式,可看作是一种特殊的一维数组,它的元素又是一个一维数组
其实二维数组 就是两个一维数组 其中的一维数组此时每个元素不是整型变量,而是具有多个整型的一维数组
//本质是一维数组的一维数组
多维数组同理 ,如三维数组是一维数组的一维数组的一维数组。
//想象成套娃一样,这样很容易理解
二维数组使用:
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};//全部初始化
int a[3][4] = {{1,2,3},{7,8,9}.{10,11,12}};//按行初始化
int a[3][4] = {1,2};
注意:
1.二维数组中,也可以是可变长数组。
2.二维数组中,可以省略行数,列数不能省略。// 如果对全部元素都赋初值,则定义数组时对第一维的长度可以不指定,但第二维的长度不能省。例如:
int a[][] = {1,2,3}; //不能这样写
系统能根据总个数和第二维的长度算出第一维的长度
int a1[][3] = {1,2,3,4}//可以推出sizeof(a1) = 24
因为一行有三个元素,而{}中有四个元素,要容纳总个数四个,最少需要两行。
下面分享一个大厂的笔试问题
strcat、strncat、strcmp、strcpy哪些函数会导致内存溢出?如何改进?
strcpy函数会导致内存溢出。
strcpy拷贝函数不安全,它不做任何的检查措施,也不判断拷贝大小,不判断目的地址内存是否够用。
char *strcpy(char *strDest,const char *strSrc)
1
strncpy拷贝函数,虽然计算了复制的大小,但是也不安全,没有检查目标的边界。
strncpy(dest, src, sizeof(dest));
strncpy_s是安全的。
strcmp(str1,str2),是比较函数,若str1=str2,则返回零;若str1<str2,则返回负数;若str1>str2,则返回正数。(比较字符串)
strncat()主要功能是在字符串的结尾追加n个字符。
char * strncat(char *dest, const char *src, size_t n);
strcat()函数主要用来将两个char类型连接。例如:
char d[20]="Golden";
char s[20]="View";
strcat(d,s);
//打印d
printf("%s",d);
//输出 d 为 GoldenView (中间无空格)
延伸:
memcpy拷贝函数,它与strcpy的区别就是memcpy可以拷贝任意类型的数据,strcpy只能拷贝字符串类型。
memcpy 函数用于把资源内存(src所指向的内存区域)拷贝到目标内存(dest所指向的内存区域);有一个size变量控制拷贝的字节数;
函数原型:
void *memcpy(void *dest, void *src, unsigned int count);