一、数组操作
1.清空数组
函数原型:void *memset( void *dest, int ch, size_t count );
(只适用于c++或c基本数据类型)
- dest:指向要填充的对象的指针
- ch:填充字节,一般用0
- count:数组占用字节大小
举例:
int a[] = {1,2,3,4,5,6};
memset(a,0,sizeof(a));//数组每个元素都变为0
2. 复制数组
函数原型:void *memcpy(void *destin, void *source, unsigned n);
(只适用于c++基本数据类型)
- dest:目标数组
- src:源数组
- n:数组占用字节大小
举例:
int a[] = {1,2,3,4,5,6};
int b[sizeof(a)/sizeof(a[0])];
memcpy(b,a,sizeof(a));//数组b就和数组a一样了
3. 数组排序
函数作用:对 ptr 所指向的数组以升序排序
函数原型:void qsort(void *ptr,size_t count,size_t size,int(*comp)(const void *,const void *));
- ptr:指向待排序的数组的指针
- count:数组的元素数目
- size:数组每个元素的字节大小
- comp:比较函数。若首个参数小于第二个,则返回负整数值,若首个参数大于第二个,则返回正整数值,若两参数等价,则返回零。
- 自己理解的就是:对比的时候,第一个指针指向的值在前,第二个指针指向的值在后。如果第一个值比第二个值大,返回正值,那么就会让qsort交换这两个值(升序),如果第一个值比第二个值小,返回负值,则qsort不会交换这两个值。(如果要降序,则相反即可)
举例:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
int compare_ints(const void* a, const void* b)
{
int arg1 = *(const int*)a;
int arg2 = *(const int*)b;
if (arg1 < arg2) return -1;
if (arg1 > arg2) return 1;
return 0;
// return (arg1 > arg2) - (arg1 < arg2); // 可行的简写
// return arg1 - arg2; // 错误的简写(若给出 INT_MIN 则会失败)
}
int main()
{
int ints[] = { -2, 99, 0, -743, 2, INT_MIN, 4 };
int size = sizeof(ints)/ sizeof((*ints));
qsort(ints, size, sizeof(int), compare_ints);
for (int i = 0; i < size; i++) {
printf("%d ", ints[i]);
}
//输出-2147483648 -743 -2 0 2 4 99
printf("\n");
}
其中
#include<limits.h>
C/C++中常量INT_MAX和INT_MIN分别表示最大、最小整数,头文件是limits.h。
INT_MAX = 2^31-1=2147483647;
INT_MIN= -2^31=-2147483648;
二、C字符串操作
1.初始化字符串
举例:
char name[11]; // 可以存放 10 个字符,没有初始化,里面是垃圾值。
char name[11] = "hello"; // 初始内容为 hello,系统会自动添加 0。
char name[] = { "hello" }; // 初始内容为 hello,系统会自动添加 0,数组长度是 6。
char name[11] = { "hello" }; // 初始内容为 hello,系统会自动添加 0。
char name[11] { "hello" }; // 初始内容为 hello,系统会自动添加 0。C++11 标准。
char name[11] = { 0 }; // 把全部的元素初始化为 0。
2.清空字符串
函数原型:void *memset(void *s,int c,size_t n);
(只适用于c++或c基本数据类型)
- s:字符串地址
- c:0
- n:字符串占用字节大小
举例:
char a[]="123123";
printf("%s\n",a); //123123
memset(a,0,sizeof(a)); //清空字符串
3.复制或赋值字符串
-
函数原型:
char *strcpy(char *dest, const char *src);
- 参数:
- dest:指向要写入的字符数组的指针
- src :指向要复制的空终止字节字符串的指针
- 返回值: dest 的起始地址
- 注意:复制完字符串后会在dest后追加
'\0'
,如果如果dest指的内存不够大,会导致数组越界。
举例:
char a[]="123123"; char b[20]; memset(b,0,sizeof(b));//清空数组b strcpy(b,a); printf("%s\n",b);//123123
- 参数:
-
函数原型:
char *strncpy(char *dest,const char *src,size_t count);
- 功能:把src前n个字符复制到dest中
- 参数:
- dest:指向要复制到的字符数组的指针
- src:指向要复制的空终止字节字符串的指针
- count:要复制的最大字符数
- 返回值: dest 的起始地址
- 注意: 如果 src 的长度大于等于 count,就截取 src 的前 count 个字符,不会在 dest 后追加 0。
举例:如果count大于src 字符串长度,则拷贝完字符串后,在 dest 后追加 0,直到count个。
char a[]="123"; char b[10]; strncpy(b,a,5); for (int i = 0; i < 12; ++i) { cout<<int(b[i])<<endl; } //输出:可以看出第4,5个用0填补,后面的就是随机值了 49 50 51 0 0 4 1 0 0 0
举例:如果count小于等于src 的长度,就截取 src 的前 count 个字符,不会在 dest 后追加 0。
char a[]="12345"; char b[10]; strncpy(b,a,4); for (int i = 0; i < 10; ++i) { cout<<int(b[i])<<endl; } //输出:可以看出从第5个开始,后面都是随机值 49 50 51 52 33 2 1 0 0 0
基于上述结论,所以推荐每次都把dest使用memset对其清空。即
memset(dest,0,sizeof(b))
,这样就不会出现上面问题。
4.获取字符串长度
函数原型:size_t strlen(const char *str );
- 参数:
- str:指向要检验的空终止字节字符串的指针
举例:计算的是字符串的实际长度,遇到'\0'
结束
char a[10]="12345";
cout<<strlen(a)<<endl;//5
cout<<sizeof(a);//10
5.字符串拼接
-
函数原型:
char *strcat(char *dest, const char *src );
- 参数:
- dest:指向要后附到的空终止字节字符串的指针
- src :指向作为复制来源的空终止字节字符串的指针
- 返回值: dest 的起始地址
- 注意:dest后的
'\0'
会被覆盖掉,并在连接后的字符串尾部新增'\0'
。 - C++直接用
+
拼接
举例:
char a[20]="12345"; char b[20]="12345"; strcat(a,b); cout<<a;//1234512345 string c="12345"; string d="12345"; cout<<c+d;//1234512345
- 参数:
-
函数原型:
char *strncat(char *dest, const char *src, size_t count );
- 功能:把src前n个字符添加到dest后面
- 参数:
- dest:指向要后附到的空终止字节字符串的指针
- src:指向作为复制来源的字符数组的指针
- count:要复制的最大字符数
- 返回值: dest 的起始地址
举例:
char a[20]="12345"; char b[10]="12345"; strncat(a,b,3); cout<<a;//12345123
6.字符串比较
-
函数原型:
int strcmp( const char *lhs, const char *rhs );
- 参数:
- lhs, rhs:指向要比较的空终止字节字符串的指针
- 返回值:
- lhs比rhs小返回负值
- 若 lhs 与 rhs 比较相等返回0
- lhs比rhs大返回负值。
举例:
char a[20]="1"; char b[20]="2"; cout<<strcmp(a,b);//-1 char c[20]="1"; char d[20]="1"; cout<<strcmp(c,d);//0 char e[20]="2"; char f[20]="1"; cout<<strcmp(e,f);//1
- 参数:
-
函数原型:
int strncmp( const char *lhs, const char *rhs );
- 参数:
- lhs, rhs:指向要比较的空终止字节字符串的指针
- count:要比较的最大字符数
- 返回值:
- lhs比rhs小返回负值
- 若 lhs 与 rhs 比较相等返回0
- lhs比rhs大返回负值。
举例:
char a[20]="12"; char b[20]="22"; cout<<strncmp(a,b,1);//-1 char c[20]="12"; char d[20]="12"; cout<<strncmp(c,d,1);//0 char e[20]="22"; char f[20]="12"; cout<<strncmp(e,f,1);//1
- 参数:
- 注意:
- 两个字符串比较的方法是比较字符的 ASCII 码的大小,从两个字符串的第一个字符开始,如果分不出大小,就比较第二个字符,如果全部的字符都分不出大小,就返回 0,表示两个字符串相等。
- 在实际开发中,程序员一般只关心字符串是否相等,不关心哪个字符串更大或更小。
7.查找字符
-
函数原型:
char *strchr(const char *str, int ch );
- 作用:寻找 ch 在 str 所指向的空终止字节字符串中的首次出现位置。
- 参数:
- str:指向待分析的空终止字节字符串的指针
- ch:要搜索的字符
- 返回值:指向 str 找到的字符的指针,若未找到该字符则为空指针。
举例:
char a[20]="157885478"; char *p = strchr(a,'8'); cout<<*p<<endl;//8 cout<<p;//885478
-
函数原型:
char *strrchr( const char *str, int ch );
- 作用:寻找 ch 在 str 所指向的空终止字节字符串中的最后出现位置。
- 参数:
- str:指向待分析的空终止字节字符串的指针
- ch:要搜索的字符
- 返回值:指向 str 找到的字符的指针,若未找到该字符则为空指针。
举例:
char a[20]="1578854789"; char *p = strrchr(a,'8'); cout<<*p<<endl;//8 cout<<p;//89
8.查找字符串
函数原型:char *strstr( const char* str, const char* substr );
- 作用:查找 substr 所指的空终止字节字符串在 str 所指的空终止字节字符串中的首次出现。
- 参数:
- str:指向要检验的空终止字节字符串的指针
- substr:指向要查找的空终止字节字符串的指针
- 返回值:指向于 str 中找到的子串首字符的指针,或若找不到该子串则为空指针。若 substr 指向空字符串,则返回 str 。
举例:
char a[20]="1578854789";
char b[20]="8854";
char *p = strstr(a,b);
cout<<*p<<endl;//8
cout<<p;//885479
比较
- memcopy和strcopy区别:
- 复制的内容不同。strcpy只能复制字符串,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等
- 复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度
- 用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
注意
- 字符串在每次使用前都要初始化。
- 不要在子函数中对字符指针用sizeof运算,这样只会输出指针所占的大小。