目录
一、一维数组
1.概念:
构造数据类型之一
-数组是具有一定顺序关系的若干个变量的集合,组成数组的各个变量称为数组的元素。
-数组中各个元素的数据类型要求相同,用数组名和下标确定。
-数组可以是一维的,也可以是多维的。
例int a[6];
数组名表示内存首地址,是地址常量sizeof(数组名)是数组占用的总内存空间
编译时分配连续内存,内存字节数 = 数组维数*sizeof(元素数据类)
2.引用
一维数组的引用
-数组必须先定义,后使用
-只能逐个引用数组元素,不能一次引用整个数组
-数组元素表示形式:数组名【下标】
其中:下标可以使常量或整形表达式
int a[10];
//printf("%d",a); (X)
for(i = 0; i<10; i++)
printf("%d\t", a[j]); (√)
3.初始化
一维数组的初始化
-初始化方式:在定义数组时,为数组元素赋初值
int a[5]={1,2,3,4,5,};
说明
-数组不初始化,其元素值为随机数 auto类型
-对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); int a[3]={6,2,3,5,1};(×) |
int a={1,2,3,4,5,6};//编译系统根据初值个数确定数组维数 |
注意
-C语言对数组不作越界检查,使用时要注意。ERROR: int a[5];a[5]=10
-关于用变量定义数组维数。int i =15;int a[i]
二、二维数组
1.概念
数据类型 数组名【常量表达式(行)】【常量表达式(列)】
定义方式:申明时列数不能省略,行数可以
-例int a[3][4];
float b[2][5];
int c[2][3][4];
元素个数=行*列。
2.存放顺序
二维数组的存放顺序:
a[0][0] 1 | a[0][1] 2 |
a[1][0] 3 | a[1][1] 4 |
a[2][0] 5 | a[2][1] 6 |
-原因:内存是一维的
-二维数组:按行序优先
3.二维数组和一维数组的区别
(1)二维数组名本身存不存在地址?存在。
(2)对它求sizeof是不是整个数组的总空间?是的
(3)a++会报错,数组名不能做这样的处理。
(4)行名,或者叫一维数组名具不具备该特征?一样。例a[2][3] 中行名a[1]
4.引用和初始化
二维数组的引用
形式:数组名【下标】【下标】
二维数组元素的初始化
-分行初始化
-按元素排列顺序初始化
例:int a[][3]={{1},{4,5}};
1 | 0 | 0 | 4 | 5 | 0 |
a[0][0] | a[0][1] | a[0][2] | a[1][0] | a[1][1] | a[1][2] |
5.多维数组
概念:具有两个或两个以上下标的数组称为多维数组。
例:打印杨辉三角的前十行
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
int main()
{
int i,j;
int a[10][10]={{0}};
for(i = 0; i< 10 ; i++)
{
for(j = 0;j<i;j++)
{
a[i][j] = a[i-1][j-1] + a[i-1][j];
}
a[i][0]=1;
}
for(i = 0; i< 10 ; i++)
{
for(j = 0;j<i;j++)
{
printf("%d ",a[i][j]);
}
putchar('\n');
}
}
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
1 7 21 35 35 21 7 1
1 8 28 56 70 56 28 8 1
#include <stdio.h>
int main()
{
int i,j,k;
int a[10][10]={{0}};
for(i = 0; i< 10 ; i++)
{
for(j = 0;j<i;j++)
{
a[i][j] = a[i-1][j-1] + a[i-1][j];
}
a[i][0]=1;
}
for(i = 0; i< 10 ; i++)
{
for(k = 9;k>i;k--)
{
printf(" ");
}
for(j = 0;j<i;j++)
{
printf("%2d ",a[i][j]);
}
putchar('\n');
}
}
思考
有一个3*4的矩阵,要求输出其中值最大的元素值,以及它的行号和列号
#include <stdio.h>
int main()
{
int i,j;
int max_i=0,max_j=0;
int a[3][4]={
{3,5,6,0},
{10,4,11,8},
{7,2,1,9}
};
for(i = 0; i< 3 ; i++)
{
for(j = 0;j<4;j++)
{
if(a[i][j]>a[max_i][max_j]){
max_i = i;
max_j = j;
}
}
}
printf("max = %d,max_i =%d,max_j = %d\n",a[max_i][max_j],max_i,max_j);
}
三、字符数组
1.概念
字符数组
字符数字是元素的数据类型为字符类型的数组
-char c[10],ch[3][4];
字符数组的初始化
-逐个字符赋值
-用字符串常量
2.初始化
字符数组的初始化
char ch[5]={'H','e','l','l','o'};
大括号也能省略
char ch[6]="hello";
char ch[6]={"hello}';
char ch[]="hello";
例 char ch[5] = {'B','o','y'};
B | o | y | \0 | \0 |
ch[0] | ch[1] | ch[2] | ch[3] | ch[4] |
0 和 '\0' 和NULL都是一个意思
char arr1[]={'a','b','c'};
char arr2[6]={'a','b','c'};
两个数组的区别:对于有了\0的arr2还是字符串,而arr1是字符数组
例题:输入一个字符串,然后将其逆序输出。
方法一、gets 和sizeof 确定个数
#include <stdio.h>
int main()
{
char buf[50]={0};
int i,n;
printf("input words\n");
gets(buf);
n = sizeof(buf)/sizeof(char);
for(i = n-1; i>=0; i--)
putchar(buf[i]);
putchar('\n');
return 0;
}
方法二 、strlen 确定个数
#include <stdio.h>
#include <string.h>
int main()
{
char buf[50]={0};
int i,n;
printf("input words\n");
gets(buf);
n = strlen(buf);
for(i = n-1; i>=0; i--)
putchar(buf[i]);
putchar('\n');
return 0;
}
方法三:定义2个下标,一个指向头,一个指向尾。如果头下标小于尾下标,交换数组元素的头和尾,都下标+1,尾下标-1,直到循环结束。
#include <stdio.h>
#include <string.h>
int main()
{
char buf[50]={0},ch;
int i,j,n;
printf("input words\n");
gets(buf);
n = strlen(buf);
i = 0;
j = n -1;
while(i < j){
ch = buf[i];
buf[i] = buf[j];
buf[j] = ch;
i++;
j--;
}
for(i = 0; i<n ; i++)
putchar(buf[i]);
putchar('\n');
return 0;
}
3.字符数组访问
#include <stdio.h>
int main()
{
char arr1[]={'a','b','c'};
char arr2[6] = {'a','b','c'};
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');
return 0;
}
字符数组的个数可以用 n= sizeof(arr1) /sieseof (char);
putchar(arr[i]) 也可以用printf("%c,arr[i]);
如果使用printf和%s会出现的现象。主要没看到\0。并且地址是连续的
#include <stdio.h>
int main()
{
char arr1[]={'a','b','c'};
char arr2[6] = {'a','b','c'};
int i, n;
printf("arr1:%s\n",arr1);
printf("arr2:%s\n",arr2);
}
arr1:abcabc
arr2:abc
4.二维字符数组初始化
例
char fruit[][6]={"Apple","Orange","Grape",''Pear",''Peach"};
char fruit[][6]={{'A','p','p','l','e'},{'O','r','a','n','g','e'},{'G','r','a','p','e'},{'P','e','a','r'},{'P','e','a','c','h'}};
fruit[0] | A | p | p | l | e | \0 |
fruit[1] | O | r | a | n | g | e |
fruit[2] | G | r | a | p | e | \0 |
fruit[3] | P | e | a | r | \0 | \0 |
fruit[4] | P | e | a | c | h | \0 |
打印二维字符数组思路 m行数等于整个字符地址大小,除以行字符地址空间大小
n列数等于行字符地址空间大小,除以字符类型大小。
#include <stdio.h>
int main()
{
int i,j;
int m,n;
char fruit[][6]={"Apple","Orange","Grape","Pear","Peach"};
m = sizeof(fruit)/sizeof(fruit[0]);
n = sizeof(fruit[0])/sizeof(char);
for(i = 0; i < m; i++){
for(j = 0; j < n; j++){
printf("%c ",fruit[i][j]);
}
putchar('\n');
}
}
A p p l e
O r a n g e
G r a p e
P e a r
P e a c h
这个代码有点点多余,如果每行都有\0,其实不用一个个字符打印,可以打印字符串。
#include <stdio.h>
int main()
{
int i,j;
int m;
char fruit[][7]={"Apple","Orange","Grape","Pear","Peach"};
m = sizeof(fruit)/sizeof(fruit[0]);
for(i = 0; i < m; i++){
printf("%s\n",fruit[i]);
}
}
Apple
Orange
Grape
Pear
Peach
四、字符串
1.概念
字符串
C语言中无字符串变量,用字符数组处理字符串,字符串结束标志:'\0'
2.函数用法
strlen
-格式:strlen(字符数组)
-功能:计算字符串长度
-返值:返回字符串时间长度,不含'\0'
-\xhh表示十六进制代表的符号
-\ddd表示8进制
例如:
#include <stdio.h>
#include <string.h>
int main()
{
char a[10]={'a','\0','b','\0','D'};
printf("%d",strlen(a)); //1
char b[]="\t\v\\\0will\n";
printf("%d",strlen(b)); //3 遇到转译的时候斜杠不算在内
char c[]="\x69\141\n"; //3 \xhh转移为16进制 i \ddd代表8进制的字符 a
printf("%d",strlen(c));
}
strcpy
-格式:strcpy(字符数组1,字符串2)
-功能:将字符串2,拷贝到字符数组1中去
-返值:返回字符数组1的首地址
-说明:
字符数组1必须足够大
拷贝时‘\0’一同拷贝
原理:
#include <stdio.h>
#include <string.h>
int main()
{
char src[] = "hello world";
char dest[100];
int i ,n;
i = 0;
n = strlen(src);
while(i<=n){
dest[i] = src[i];
i++;
}
puts(src);
puts(dest);
}
strcat
-格式:strcat(字符数组1,字符数组2)
-功能:把字符数组2连到字符数组1后面
-返值:返回字符数组1的首地址
-说明:
字符数组1必须足够大
连接前,两串均以'\0'结束;连接后串1的'\0'取消,新串最后加'\0'
#include <stdio.h>
#include <string.h>
int main()
{
char str1[20] = "hello world";
char str2[] = ".com.cn";
strcat(str1,str2);
puts(str1);
puts(str2);
}
hello world.com.cn
.com.cn
如果不加\0
#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = {'a','b','c'};
char str2[] = ".com.cn";
strcat(str1,str2);
puts(str1);
puts(str2);
}
abc.com.cn.com.cn
.com.cn.com.cn
strcmp
-格式:strcmp(字符串1,字符串2)
-功能:比较两个字符串
-比较规则:对两串从左向右逐个字符比较(ACKII码),直到遇到不同字符或'\0'
-返值:返回int型整数
a.若字符串1<小于字符串2,返回负整数
b.若字符串1>大于字符串2,返回正整数
c.若字符串1==字符串2,返回0
3.扩展用法
strncpy(p,p1,n)复制指定长度字符串
#include <stdio.h>
#include <string.h>
int main()
{
char src[] = "abcdefg";
char dest[] = ".com.cn";
strncpy(dest,src,4);
puts(src);
puts(dest);
}
abcdefg
abcd.cn
strncat(p,p1,n)附加指定长度字符串
#include <stdio.h>
#include <string.h>
int main()
{
char src[] = "abcdefg";
char dest[] = ".com.cn";
strncat(dest,src,4);
puts(src);
puts(dest);
}
abcdefg
.com.cnabcd
strcasecmp忽略大小写比较字符串
#include <stdio.h>
#include <string.h>
int main()
{
char src[] = "abcdefg";
char dest[] = "ABCD";
int n,m;
n = strncmp(dest,src,4);
m = strncasecmp(dest,src,4);
printf("%d\n",n);
printf("%d\n",m);
}
-1
0
strncmp(p,p1,n)比较指定长度字符串)
strchr(p,c)在字符串中查找指定字符(第一次出现)
#include <stdio.h>
#include <string.h>
int main()
{
char src[] = "abcdefg";
printf("%p %p \n",src, strchr(src,'d'));
}
0xbf911844 0xbf911847
strrchr(最后一次出现)
-p代表字符串,c代表特点字符
#include <stdio.h>
#include <string.h>
int main()
{
char src[] = "abcdefgd";
printf("%p %p \n",src, strrchr(src,'d'));
}
0xbf8d7dc3 0xbf8d7dca
strstr(p,p1)查找字符串
#include <stdio.h>
#include <string.h>
int main()
{
char src[] = "abcdefgd";
printf("%p %p %d\n",src, strstr(src,"bcd"),strstr(src,"bcd")-src);
}
0xbfc49343 0xbfc49344 1
4.扩展用法2
#includ<ctype.h>
man isalpha查看命令描述和返回值
NAME
isalnum, isalpha, isascii, isblank, iscntrl, isdigit, isgraph, islower, isprint, ispunct, isspace, isupper, isxdigit - character classification routines
SYNOPSIS
#include <ctype.h>
int isalnum(int c);
int isalpha(int c);
int isascii(int c);
int isblank(int c);
int iscntrl(int c);
int isdigit(int c);
int isgraph(int c);
int islower(int c);
int isprint(int c);
int ispunct(int c);
int isspace(int c);
int isupper(int c);
int isxdigit(int c);
RETURN VALUE
The values returned are nonzero if the character c falls into the tested class, and a zero value if not.
isalpha()检查是否为字母字符
isupper()检查是否为大写字母字符
islower()检查是否为小写字母字符
isdigit()检查是否为数字
toupper()大写转换
tolower()小写转换
例:大写转小写,小写转大写
#include <stdio.h>
#include <ctype.h>
int main(int argc,char *argv[]){
int ch;
while((ch = getchar()) != EOF){
if (isalpha(ch)){
if (isupper(ch)) {
ch = tolower(ch);
}
else {
ch = toupper(ch);
}
printf("%c\n",ch);
}
}
return 0;
}
总结题
从终端输入10个数字(乱序),利用简单选择排序法对这10个数字排序,结果从大到小排列。
冒泡排序和简单选择排序是两个不同的原理。如果不会,可以上网查阅资料
#include <stdio.h>
#include <ctype.h>
#define N 100
int main(int argc,char *argv[]){
int buf[N]={0};
int i,j,n,temp;
printf("how many numbers? :\n");
scanf("%d",&n); //输入数字的个数
printf("please input:\n");
for(i = 0; i < n; i++){
scanf("%d",&buf[i]); //循环接受数字
}
//冒泡算法
for(i = 0; i < n; i++)
{
for(j = i+1;j < n; j++)
{
if(buf[j]>= buf[i]){
temp = buf[i];
buf[i] = buf[j];
buf[j] = temp;
}
}
}
//遍历打印
for(i = 0 ; i<n; i++){
printf("%d ",buf[i]);
}
}