字符串操作函数
字符串拷贝函数 strcpy、strncpy
#include <string.h>
char *strcpy(char *dest, const char *src);
功能:实现字符串复制(复制包括 '\0')
参数: char *dest:目标字符串首地址
const char *src:源字符串首地址
返回值:目标字符串首地址
#include <string.h>
char *strncpy(char *dest, const char *src, size_t n);
// n 为源字符串的前 n 个字符。
字符串连接函数 strcat、strncat
#include <string.h>
char *strcat(char *dest, const char *src);
功能:用于字符串拼接
参数: char *dest:目标字符串的首地址
const char *src:源字符串的首地址
返回值:目标字符串的首地址
#include <string.h>
char *strncat(char *dest, const char *src, size_t n);
// n 为源字符串的前 n 个字符。
#include <stdio.h>
#include <string.h>
#define N 20
int main(int argc, char const *argv[])
{
char dest[N] = "Nos "; // N要足够大,以容纳拼接后的数组
char src[] = "vemos. ";
strncat(dest, src, 5);
puts(dest);
return 0;
}
运行结果如下:
字符串比较函数 strcmp
#include <string.h>
int strcmp(const char *s1, const char *s2);
功能:用于字符串的比较
参数:s1、s2:用于比较的字符串的地址
返回值:从字符串首个字符开始比较字符的 ASCII 的大小,如果相等则继续向后判断
s1 > s2 返回 1
s1 == s2 返回 0
s1 < s2 返回 -1
#include <string.h>
int strncmp(const char *s1, const char *s2, size_t n);
// 比较两个字符串前 n 个字符的大小。
求字符串长度函数 strlen
#include <string.h>
size_t strlen(const char *s);
功能:计算字符串的实际长度(不包括 '\0')
参数:要计算的字符串的首地址
返回值:字符串的实际长度
计算字符串的实际长度
1)利用 puts(str); // 包括’\0’
2)利用 printf(“%s”, str); // 不包括’\0’
#include <stdio.h>
int main(int argc, char const *argv[])
{
char *str1 = "Hello!";
char str2[] = "Hola!"; // 中括号内可填入>=5的任意数字,也可不填
char str3[] = {'A', 'l', 'o', 'h', 'a', '!'}; // 此法定义无'\0'
printf("%s\n", str1);
int num = puts(str2);
printf("%d\n", sizeof(str1)); // 所有类型的指针在32位机上都占32位(4个字节)
printf("%d\n", sizeof(str2));
printf("%d\n", sizeof(str3));
printf("%d\n", num); // puts(str); 包括'\0'
printf("%d\n", printf("%s", str2)); // printf("%s", str); 不包括'\0'
return 0;
}
运行结果如下:
3)利用循环
for循环遍历数组,直到 ‘\0’ 为止
for(int n = 0; buf[n] != ‘\0’; n++)
4)strlen(str);
5)sizeof(str); // 数组长度省略的前提下,即char str[]=… 时
sizeof 和 strlen 的区别
#include<stdio.h>
#include<string.h>
int main(int argc, char const *argv[])
{
char a[] = "hello";
int ret = sizeof(a); // ret == 6,若 a[18] 则 ret == 18
int num = strlen(a); // num == 5
printf("%d %d\n", ret, num);
return 0;
}
1、sizeof 是关键字,strlen是函数;
2、sizeof 是计算数据所占空间大小,strlen计算字符串的实际长度;
3、sizeof 计算包括 ‘\0’,strlen 计算不包括 ‘\0’。(元素个数省略的情况下,sizeof 比 strlen 大1)
排序
冒泡排序
int arr[5] = {5, 4, 3, 2, 1};
第一轮:
45321
43521
43251
43215
第二轮:
34215
32415
32145
第三轮:
23145
21345
第四轮
12345
// 升序的冒泡排序
#include <stdio.h>
#define N 10
void bubble_1(int *a);
void bubble_2(int *a);
int main(int argc, char const *argv[])
{
int arr[N];
for (int i = 0; i < N; i++)
scanf("%d", &arr[i]);
bubble_1(arr);
bubble_2(arr);
return 0;
}
bubble_1(int *a){ // 最大数被安置在最后
int temp;
for (int i = 0; i < N-1; i++) // n-1 轮,每一轮确定一个max
for (int j = 0; j < N-1-i; j++) // 若不考虑代码执行时间或效率,可限制 j < N-1
if (a[j] > a[j+1]){ // 具体某轮的比较,若降序则只需更改大于号
temp = a[j];
a[j] = a[j+1];
a[j+1] = temp;
}
for (int i = 0; i < N; i++)
printf("%6d", a[i]);
printf("\n");
}
bubble_2(int *a){ // 最小数被安置在最前
int temp;
for (int i = 0; i < N-1; i++) // n-1 轮,每一轮确定一个min
for (int j = N-1-i; j > 0; j--) // j < N-1-i,每一轮两两比较的数字数量-1
if (a[j-1] > a[j]){ // a[j] 与前一项比较
temp = a[j];
a[j] = a[j-1];
a[j-1] = temp;
}
for (int i = 0; i < N; i++)
printf("%6d", a[i]);
printf("\n");
}
选择排序
// 升序的选择排序
#include <stdio.h>
#define N 10
void select_1(int *a);
void select_2(int *a); // N 较小时,选择排序优于冒泡排序
int main(int argc, char const *argv[])
{
int arr[N];
for (int i = 0; i < N; i++)
scanf("%d", &arr[i]);
select_1(arr);
select_2(arr);
return 0;
}
select_1(int *a){ // 最小数被安置在最前
int k, temp;
for (int i = 0; i < N-1; i++){ // i < N-1,因为下面 j = i+1
k = i; // 假定 当前min=a[k]=a[i] 最小
for (int j = i+1; j < N; j++)
if (a[j] < a[k]) // 后一项 < 前一项,则标记当前的 min 下标
k = j; // 若降序,则只需将小于号改为大于号
if (k != i){ // 若当前 min=a[k] 与 a[i] 不同,则交换
temp = a[i];
a[i] = a[k];
a[k] = temp;
}
}
for (int i = 0; i < N; i++)
printf("%6d", a[i]);
printf("\n");
}
select_2(int *a){ // 最大数被安置在最后
int k, temp;
for (int i = N-1; i > 0; i--){ // i > 0,因为下面 j = i-1
k = i; // 假定 当前max=a[k]=a[i] 最大
for (int j = i-1; j >= 0; j--)
if (a[k] < a[j]) // 后一项 < 前一项,则标记当前的 max 下标
k = j;
if (k != i){ // 若当前 max=a[k] 与 a[i] 不同,则交换
temp = a[i];
a[i] = a[k];
a[k] = temp;
}
}
for (int i = 0; i < N; i++)
printf("%6d", a[i]);
printf("\n");
}
二维数组
定义格式
<存储类型> <数据类型> <数组名字>[常量表达式1][常量表达式2]
存储类型指的是auto,register, static,extern。其中 auto 可以省略。
e.g.
int arr[2][3];
数组名 & 内存分配
arr:第一行的首地址(整个数组的首地址)
arr+1:第二行的首地址
…
#include <stdio.h>
int main(int argc, char const *argv[])
{
int a[2][3];
// for (int i = 0; i < 2; i++)
// for (int j = 0; j < 3; j++)
// scanf("%d", &a[i][j]);
for (int i = 0; i < 2; i++){
for (int j = 0; j < 3; j++)
printf("%p ", &a[i][j]);
putchar(10);
}
printf("%p\n", &a);
for (int i = 0; i < 2; i++)
printf("%p\n", &a[i]);
putchar(10);
return 0;
}
运行结果如下:
访问元素
数组名[行下标][列下标],下标从0开始。下标只能是整型常量或整型表达式。
访问第一行第一列的元素:arr[0][0]
访问第 n 行第 n 列的元素:arr[n-1][n-1]
输入第 i 行第 i 列元素:scanf(“%d”, &arr[i-1][i-1]);
初始化
全部初始化
按行初始化
int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};
int arr[ ][3] = {{1, 2, 3}, {4, 5, 6}}; // 可以省略行下标
顺序初始化
int arr[2][3] = {1, 2, 3, 4, 5, 6};
int arr[ ][3] = {1, 2, 3, 4, 5, 6}; // 第二维的长度不能省略,否则报错
部分初始化
按行初始化
int arr[2][3] = {{1}, {2}}; // 1、0、0; 2、0、0
顺序初始化
int arr[2][3] = {1, 2}; // 1、2、0; 0、0、0
数组大小
sizeof(arr);
二维数组大小 = 数据类型大小 * 元素个数
元素个数 = 行数 * 列数
遍历
双层循环即可。