文章目录
1、数组
数组
-
构造数据类型之一(如char s[5])
-
数组是具有一定顺序关系的若干个变量的集合,组成数组的各个变量称为数组的元素
-
数组中各元素的数据类型要求相同,用数组名和下标确定。数组可以是一维的,也可以是多维的。
1.1 一维数组
1.1.1一维数组的定义
-
所谓一维数组是指只有一个下标的数组。它在计算机的内存中是连续存储的。
-
C语言中,一维数组的说明一般形式如下:
<存储类型> <数据类型 > <数组名>[<表达式>] ;
例: int a[6];
- 数组名(a)表示内存首地址,是地址常量sizof(数组名)是数组占用的总内存空间
- 编译时分配连续内存内存字节数=数组维数*sizeof(元素数据类型)
例如:
#include <stdio.h>
int main(int argc, char *argv[])
{
//int i = 6, a[i];
int a[6] = {1, 4, 5}, i, n;
int b[] = {3, 4, 7, 8, 1, 0};
n = sizeof(b) / sizeof(int);
for (i = 0; i < n; i++)
//printf("%p %d ", &a[i], a[i]);
printf("%p %d\n", &b[i], b[i]);
//a = a + 1;
printf("%p\n", a);
printf("%d\n", sizeof(a));
return 0;
}
其中%p是查看地址
注意事项:
-
C语言对数组不作越界检查,使用时要注意。
a[5]–>a[0]、a[1]、a[2]、a[3]、a[4]
int a[5]; a[5] = 10
-
关于用变量定义数组维数
int i = 15; int a[i]
1.1.2 一维数组的引用
- 数组必须先定义,后使用
- 只能逐个引用数组元素,不能一次引用整个数组
- 数组元素表示形式:数组名[下标]
- 其中:下标可以是常量或整型表达式
例如:
int a[10];
printf("%d", a); (×)
for(j=0;j<10;j++)
printf("%d\t", a[j]); (√)
1.1.3 一维数组的初始化
初始化方式:在定义数组时,为数组元素赋初值
int a[5]={1,2,3,4,5};
说明:
-
数组不初始化,其元素值为随机数
-
对static数组元素不赋初值,系统会自动赋以0值
-
只给部分数组元素赋初值
例如:
static int a[5];
等价于:a[0]=0; a[1]=0; a[2]=0; a[3]=0; a[4]=0;
int a[5]={6,2,3};
等价于:a[0]=6; a[1]=2;a[2]=3; a[3]=0; a[4]=0;
int a[3]={6,2,3,5,1}; (×)
int a[]={1,2,3,4,5,6};//编译系统根据初值个数确定数组维数
例如:冒泡排序
#include <stdio.h>
int main(int argc, char *argv[])
{
int a[] = {3, 4, 17, 8, 31, 2, 9, 15}, n, i, j;
int t;
n = sizeof(a) / sizeof(int);//求元素个数-
for (i = 0; i < n-1; i++) {
for (j = 0; j < n-1-i; j++) {
if (a[j] > a[j+1]){//0---
t = a[j];
a[j] = a[j+1];
a[j+1] = t;
}
}
}
for (i = 0; i < n; i++)
printf("%d ", a[i]);
puts("");
return 0;
}
1.2 二维数组
1.2.1 二维数组的定义
定义方式:(声明时列数不能省略,行数可以)>
数据类型 数组名[常量表达式][常量表达式];
例如:
int a[3][4];
二维数组a是由3个元素组成
每个元素a[i]由包含4个元素的一维数组组成
第一个[]里是行、第二个[]是列
数组元素的存放顺序
-
原因:内存是一维的
-
二维数组:按行序优先
例:
#include <stdio.h>
int main(int argc, char *argv[])
{
int a[2][3];
int i, j;
for (i = 0; i < 2; i++) {
for (j = 0; j < 3; j++)
printf("%p ", &a[i][j]);
putchar('\n');
}
printf("%p %d\n", a, sizeof(a));
printf("%p %d\n", a[0], sizeof(a[0]));
printf("%p %d\n", a[1], sizeof(a[1]));
return 0;
}
1.2.2 二维数组元素的引用
形式:数组名[下标][下标]
二维数组元素的初始化
-
分行初始化
-
按元素排列顺序初始化
例如:
int a[2][3]={{1,2,3},{4,5,6}}; 全部初始化
int a[2][3]={{1,2},{4}}; 部分初始化
int a[][3]={{1},{4,5}}; 第一维长度(行数)省略初始化
1.3 多维数组
具有两个或两个以上下标的数组称为多维数组。
例如:
int c[2][3][4]
例如:打印杨辉三角的前十行
#include <stdio.h>
int main(int argc, char *argv[])
{
int a[10][10] = {{0}};
int i, j;
for (i = 0; i < 10; i++) {
a[i][0] = 1;
for (j = 1; j <= i; j++)
a[i][j] = a[i-1][j-1] + a[i-1][j];
}
for (i = 0; i < 10; i++) {
for (j = 0; j <= i; j++)
printf("%-8d ", a[i][j]);
putchar('\n');
}
return 0;
}
解决:有一个3×4的矩阵,要求输出其中值最大的元素的值,以及它的行号和列号
#include <stdio.h>
int main(int argc, char *argv[])
{
int a[2][3] = {{2, 5, 8}, {21, 56, 9}};
int i, j, row, column;
row = column = 0;
for (i = 0; i < 2; i++) {
for (j = 0; j < 3; j++) {
if (a[row][column] < a[i][j]) {
row = i;
column = j;
}
}
}
for (i = 0; i < 2; i++) {
for (j = 0; j < 3; j++)
printf("%5d ", a[i][j]);
putchar('\n');
}
printf("max=%d %d %d\n", a[row][column], row, column);
return 0;
}
2、字符数组和字符串
2.1 字符数组
字符数组是元素的数据类型为字符类型的数组
char c[10], ch[3][4];
字符数组的初始化
-
逐个字符赋值
char ch[5]={‘B’,’o’,’y’};
-
用字符串常量
char ch[5]={"Boy"};
例如:
#include <stdio.h>
int main(int argc, char *argv[])
{
char arr1[] = {'a', 'b', 'c'};
char arr2[6] = {'d', 'e', 'f'};
printf("arr1:%s %p\n", arr1, &arr1[2]);
printf("arr2:%s %p\n", arr2, arr2);
#if 0
int i, n;
n = sizeof(arr1) / sizeof(char);
for (i = 0; i < n; i++)
putchar(arr1[i]);
putchar('\n');
n = sizeof(arr2) / sizeof(char);
for (i = 0; i < n; i++)
putchar(arr2[i]);
putchar('\n');
#endif
return 0;
}
例如:char fruit[][7]={“Apple”,”Orange”, ”Grape”,”Pear”,”Peach”};
fruit[0] | A | p | p | l | e | \0 | \0 |
---|---|---|---|---|---|---|---|
fruit[1] | O | r | a | n | g | e | \0 |
fruit[2] | G | r | a | p | e | \0 | \0 |
fruit[3] | P | e | a | r | \0 | \0 | \0 |
fruit[4] | P | e | a | c | h | \0 | \0 |
#include <stdio.h>
int main(int argc, char *argv[])
{
char fruit[][20] = {"banana", "apple", "strawmerry", "watermelen"};
int i, n;
// int j, m;
n = sizeof(fruit) / sizeof(fruit[0]);//求行
// m = sizeof(fruit[0]) / sizeof(char); //求列
for (i = 0; i < n; i++) {
printf("%s\n",fruit[i]);
// for (j = 0; j < m; j++)
// putchar(fruit[i][j]);
// putchar('\n');
}
return 0;
}
2.2字符串
C语言中无字符串变量,用字符数组处理字符串
字符串结束标志:‘\0’
例如:“hello”共5个字符,在内存占6个字节,字符串长度5
例:输入一个字符串,然后将其逆序输出
方法一:直接倒序输出
#include <stdio.h>
#include <string.h>
#define N 20
int main(int argc, char *argv[])
{
//char arr[] = "welcome";
char arr[N] = {0};
int i, n;
printf("Please input a string:");
gets(arr);
n = strlen(arr);
for (i = n-1; i >= 0; i--)
putchar(arr[i]);
putchar('\n');
return 0;
}
方法二:先反转字符串,在输出
#include <stdio.h>
#include <string.h>
#define N 20
int main(int argc, char *argv[])
{
char arr[N] = {0};
int i, j, n, ch;
printf("Please input a string:");
gets(arr);
n = strlen(arr);
i = 0;
j = n-1;
while (i < j) {
ch = arr[i];
arr[i] = arr[j];
arr[j] = ch;
i++;
j--;
}
puts(arr);
return 0;
}
3、字符串函数
C库中实现了很多字符串处理函数
#include <string.h>
几个常见的字符串处理函数
- 求字符串长度的函数strlen
- 字符串拷贝函数strcpy
- 字符串连接函数strcat
- 字符串比较函数strcmp
3.1 字符串长度函数strlen
-
格式:strlen(字符数组)
-
功能:计算字符串长度
-
返值:返回字符串实际长度,不包括 ‘\0’ 在内
-
\xhh> 表示十六进制数代表的符号
-
\ddd> 表示8进制的
例如:对于以下字符串,strlen(s)的值为:
char s[10]={‘A’,‘\0’,‘B’,‘C’,‘\0’,‘D’};
char s[ ]=“\t\v\\\0will\n”;
char s[ ]=“\x69\141\n”;
答案:1 3 3
例子1:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
//char s1[10] = {'A', '0', 'B', '\0', 'C'};
char s1[] = "makeru";
printf("%d\n", strlen(s1));
printf("%d\n", sizeof(s1)/sizeof(char));
return 0;
}
例子2:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char s1[] = "\tab\nc\vd\\e";
char s2[]= "\x69\141";
printf("%d\n", strlen(s1));
printf("%d\n", sizeof(s1)/sizeof(char));
printf("\n%d\n", strlen(s2));
printf("%d\n", sizeof(s2)/sizeof(char));
puts(s2);
return 0;
}
3.2 字符串拷贝函数strcpy
- 格式:
strcpy(字符数组1,字符串2)
- 功能:将字符串2,拷贝到字符数组1中去
- 返值:返回字符数组1的首地址
- 说明:
- 字符数组1必须足够大
- 拷贝时‘\0’一同拷贝
例子:
#include <stdio.h>
#include <string.h>
#define N 30
int main(int argc, char *argv[])
{
char src[] = "aaa";
char dest[N] = ".com.cn";
strcpy(dest, src);
puts(src);
puts(dest);
return 0;
}
3.3 字符串连接函数strcat
- 格式:
strcat(字符数组1,字符数组2)
- 功能:把字符数组2连到字符数组1后面
- 返值:返回字符数组1的首地址
- 说明:
- 字符数组1必须足够大
- 连接前,两串均以‘\0’结束;连接后,串1的‘\0’取消,新串最后加‘\0’
例子:
#include <stdio.h>
#include <string.h>
#define N 30
int main(int argc, char *argv[])
{
char src[] = "aaa";
char dest[N] = ".com.cn";
strcat(dest, src);
puts(src);
puts(dest);
return 0;
}
例子:
#include <string.h>
#include <stdio.h>
int main()
{
char destination[25];
char blank[] = " ", c[]= "C++",
turbo[] = "Turbo";
strcpy(destination, turbo);
strcat(destination, blank);
strcat(destination, c);
printf("%s\n", destination);
return 0;
}
3.4 字符串比较函数strcmp
- 格式:
strcmp(字符串1,字符串2)
- 功能:比较两个字符串
- 比较规则:对两串从左向右逐个字符比较(ASCII码),直到遇到不同字符或‘\0’为止
- 返值:返回int型整数
a. 若 字符串1 < 字符串2, 返回负整数
b. 若 字符串1 > 字符串2, 返回正整数
c. 若 字符串1 == 字符串2, 返回零
例子:
#include <stdio.h>
#include <string.h>
#define N 30
int main(int argc, char *argv[])
{
char s1[] = "QUIT";
char s2[] = "quit";
printf("%d\n", strcmp(s1, s2));
printf("%d\n", strcasecmp(s1, s2));
return 0;
}
3.5 字符串函数
strncpy(p, p1, n) 复制指定长度字符串
strncat(p, p1, n) 附加指定长度字符串
strcasecmp 忽略大小写比较字符串
strncmp(p, p1, n) 比较指定长度字符串
strchr(p, c) 在字符串中查找指定字符
strstr(p, p1) 查找字符串
isalpha() 检查是否为字母字符
isupper() 检查是否为大写字母字符
islower() 检查是否为小写字母字符
isdigit() 检查是否为数字
- strncpy
#include <stdio.h>
#include <string.h>
#define N 30
int main(int argc, char *argv[])
{
char src[] = "aaa";
char dest[N] = ".com.cn";
strncpy(dest, src, 4);
puts(src);
puts(dest);
return 0;
}
- strncat
#include <stdio.h>
#include <string.h>
#define N 30
int main(int argc, char *argv[])
{
char src[] = "aaa";
char dest[N] = ".com.cn";
strncat(dest, src, 4);
puts(src);
puts(dest);
return 0;
}
- strchr
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char s1[] = "abas$f$sf";
int ch;
ch = '$';
//printf("%p %p \n", s1, strchr(s1, ch));
//printf("%p %p \n", s1, strrchr(s1, ch));
printf("%d\n", strchr(s1, ch)-s1);
printf("%d \n", strrchr(s1, ch)-s1);
return 0;
}
- strncmp
#include <stdio.h>
#include <string.h>
#define N 30
int main(int argc, char *argv[])
{
char s1[] = "QUIT";
char s2[] = "quit";
printf("%d\n", strncmp(s1, s2, 4));
printf("%d\n", strcasecmp(s1, s2));
return 0;
}
- strstr
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char s[] = "how are you";
char subs[] = "are";
printf("%d\n", strstr(s, subs)-s);
return 0;
}
- isalpha
#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
int ch;
while ((ch = getchar()) != EOF) {
if (isalpha(ch)) {
if (isupper(ch))
printf("Upper:%c\n", ch);
if (islower(ch))
printf("Lower:%c\n", ch);
}
if (isdigit(ch))
printf("Digit:%d %c\n", ch-'0', ch);
putchar(ch);
}
return 0;
}
include <string.h>
int main(int argc, char *argv[])
{
char s[] = “how are you”;
char subs[] = “are”;
printf("%d\n", strstr(s, subs)-s);
return 0;
}
- isalpha
```c
#include <stdio.h>
#include <ctype.h>
int main(int argc, char *argv[])
{
int ch;
while ((ch = getchar()) != EOF) {
if (isalpha(ch)) {
if (isupper(ch))
printf("Upper:%c\n", ch);
if (islower(ch))
printf("Lower:%c\n", ch);
}
if (isdigit(ch))
printf("Digit:%d %c\n", ch-'0', ch);
putchar(ch);
}
return 0;
}