1. 一维数组的使用
数组:
构造数据类型之一
数组是具有一定顺序关系的若干个变量的集合,组成数组的各个变量称为数组的元素
数组中的各元素的数据类型要求相同,用数组名和下标确定。数组可以是一维的也可以是多维的
一维数组:
所谓的一维数组是指只有一个下标的数组,它在计算机内的内存中是连续存储的
C语言中,一维数组的说明一般形式如下:
<存储类型> <数据类型> <数组名>[<表达式>];
例如:int a[6];
数组名是一个地址常量
注意事项
C中数组不对边界进行检查,使用时要注意
一维数组的引用
数组必须先定义后使用
数组只能逐个引数组元素,不能想着直接用数组名一次引用整个数组
数组元素表示形式:数组名[下标],下标可以是常量或整型表达式,不能是变量
一维数组的初始化
初始化,在定义数组时,为数组元素赋元素初值
int a[5] = {1,2,3,4,5};
说明:
数组不初始化,其值为随机数
对static数组元素不赋初值,系统会自动赋以0值
可以只给部分数组赋初值,不赋值的元素自动赋0值
/*案例1:创建一个数组,内有6个元素,打印这6个元素的地址(%p打印地址)demo1*/
#include <stdio.h>
int main(int argc,char *argv[])
{
int a[6],i;
for(i = 0;i < 6;i++)
printf("%p\n",&a[i]);
return 0;
}
/*
打印结果:
linux@ubuntu:~/C/day05$ gcc demo1.c
linux@ubuntu:~/C/day05$ ./a.out
//前两行为Ubuntu下的命令行代码,意思是编译源代码,执行编译后的代码,一下才是结果
//可能你打印的结果不是这个,不同时间段,所占用的内存地址基本上都不同,但本质每个int类型中相差四个字节是一样的
0xbfc1c874
0xbfc1c878
0xbfc1c87c
0xbfc1c880
0xbfc1c884
0xbfc1c888
*/
/*案例2:冒泡排序,升序 demo2*/
#include <stdio.h>
int main(int argc,char *argv[])
{
int data[] = {49,38,97,76,13,27,30},temp;
int i,j,n;
n = sizeof(data)/sizeof(data[0]);
for(i = 0;i < n;i++){
for(j = i+1;j < n;j++){
if(data[j] < data[i]){
temp = data[i];
data[i] = data[j];
data[j] = temp;
}
}
}
for(i = 0;i < n;i++){
printf("%d ",data[i]);
}
puts("");
return 0;
}
/*
代码结果:
linux@ubuntu:~/C/day05$ gcc demo2.c -Wall
linux@ubuntu:~/C/day05$ ./a.out
//前两行为Ubuntu下的命令行代码,意思是编译源代码,执行编译后的代码,一下才是结果
13 27 30 38 49 76 97
*/
2. 二维数组的使用
二维数组的定义
定义方式:(声明时列数不能省略,行数可以[声明并赋值的时候可省]。第一个常量表达式为行[可省],第二个常量表达式为列[不可省])
数据类型 数组名[常量表达式][常量表达式];
例:int a[3][5];
数组元素的存放顺序
原因:内存是一维的
二维数组:按行序优先
二维数组的理解:
可以将二维数组的每一行当作一个一维数组,即二维数组,由多个一维数组叠成
二维数组的引用
形式:数组名[下标][下标]
二维数组的初始化
分行初始化
例:int a[2][3]={{1,2,3},{4,5,6}};
按元素排列初始化
/*案例1:创建一个二维数组,内有三行四列元素,打印这12个元素的地址(%p打印地址),且打印每行的首地址demo3*/
#include <stdio.h>
int main(int argc,char *argv[])
{
int a[3][4];
int i,j;
for(i = 0;i < 3;i++){
for(j = 0;j < 4;j++)
printf("%p ",&a[i][j]);
printf("\n");
}
printf("---------------------------\n");
printf("a[0] %p %d\n",a[0],sizeof(a[0]));
printf("a[1] %p %d\n",a[1],sizeof(a[1]));
printf("a[2] %p %d\n",a[2],sizeof(a[2]));
return 0;
}
/*
打印结果:
linux@ubuntu:~/C/day05$ gcc demo3.c -Wall
linux@ubuntu:~/C/day05$ ./a.out
//前两行为Ubuntu下的命令行代码,意思是编译源代码,执行编译后的代码,一下才是结果
0xbfba5928 0xbfba592c 0xbfba5930 0xbfba5934
0xbfba5938 0xbfba593c 0xbfba5940 0xbfba5944
0xbfba5948 0xbfba594c 0xbfba5950 0xbfba5954
---------------------------
a[0] 0xbff7a4c8 16
a[1] 0xbff7a4d8 16
a[2] 0xbff7a4e8 16
*/
/*案例2:打印杨辉三角的前十行,用二维数组进行保存,demo4.c*/
#include <stdio.h>
int main(int argc,char *argv[])
{
int i,j;
int a[10][10] = {1};
//若要去除警告,将上边一行代码改成下续代码即可
/*
int a[10][10];
for(i = 0;i < 10;i++){
for(j = 0;j <= 10;j++)
a[i][j] = 0;
}
a[0][0] = 1;
*/
for(i = 1;i < 10;i++){
a[i][0] = 1;
for(j = 1;j < 10;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("%-4d",a[i][j]);
printf("\n");
}
return 0;
}
/*
打印结果
linux@ubuntu:~/C/day05$ gcc demo4.c -Wall
demo4.c: In function ‘main’:
demo4.c:4:2: warning: missing braces around initializer [-Wmissing-braces]
demo4.c:4:2: warning: (near initialization for ‘a[0]’) [-Wmissing-braces]
//上三行为警告,用-Wall可显示出警告,警告不影响代码运行
linux@ubuntu:~/C/day05$ ./a.out
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
1 9 36 84 126 126 84 36 9 1
*/
/*案例3:有一个3*4的矩阵,要求输出其中最大的元素的值,以及它的行号和列号*/
#include <stdio.h>
int main(int argc,char *argv[])
{
int a[3][4] = {{7, 10, 12, 3},{23,3,54,23},{12,3,21,18}};
int num,h,l,i,j;
num = a[0][0];
h = 0;
l = 0;
for(i = 0;i < 3;i++){
for(j = 0;j < 4;j++){
if(a[i][j] > num){
num = a[i][j];
h = i;
l = j;
}
}
}
for(i = 0;i < 3;i++){
for(j = 0;j < 4;j++){
printf("%-4d",a[i][j]);
}
printf("\n");
}
printf("max=%d h=%d l=%d\n",num,h + 1,l + 1);
return 0;
}
/*
打印结果:
linux@ubuntu:~/C/day05$ gcc demo5.c -Wall
linux@ubuntu:~/C/day05$ ./a.out
7 10 12 3
23 3 54 23
12 3 21 18
max=54 h=2 l=3
*/
3. 多维数组的使用
多维数组
具有两个或两个以上下标的数组称为多维数组
4. 字符数组和字符串
4.1 字符数组的用法
字符数组
字符数组是元素的数据类型为字符类型的数组
字符数组的初始化
逐个字符赋值
用字符串常量
4.2 字符串的用法
C语言中无字符串变量,用字符数组处理字符串
字符串结束标志:'\0'
有'\0'为字符串,无'\0'为字符数组
/*案例1*/
#include <stdio.h>
int main(int argc,char *argv[])
{
char fruit[][20] = {"banana","apple","strawmerry","watermelen"};
int i, h;
h = sizeof(fruit)/sizeof(fruit[0]);
for(i = 0;i < h;i++){
printf("%s\n",fruit[i]);
}
return 0;
}
/*
打印结果:
linux@ubuntu:~/C/day05$ gcc demo6.c -Wall
linux@ubuntu:~/C/day05$ ./a.out
banana
apple
strawmerry
watermelen
*/
/*案例2:输入一个字符串,然后将其逆序输出*/
#include <stdio.h>
//#include <string.h> //内含string函数
int main(int argc,char *argv[])
{
char str[100];
int i;
printf("please input string(<100):");
gets(str);
for(i = 0;i < 100;i++){
if(str[i] == '\0') break;
}
/*
上三行可用函数来实现:
i = strlen(str);
同时也需要在main函数上边导入头文件
*/
for(i--;i >= 0;i--)
printf("%c",str[i]);
printf("\n");
return 0;
}
/*
打印结果:
linux@ubuntu:~/C/day05$ gcc demo7.c -Wall
linux@ubuntu:~/C/day05$ ./a.out
please input string(<100):hello world! liu zhiqing love zhangtiantian
naitnaitgnahz evol gniqihz uil !dlrow olleh
*/
5. 字符串函数
C库中的实现了很多字符串处理函数,在
#include <string.h> 头文件中定义了
5.1 求字符串长度的函数strlen
格式:
strlen(字符数组)
功能:
计算字符串长度
返值:
返回字符串实际长度,不包括'\0'在内
/*案例demo8.c*/
#include <stdio.h>
#include <string.h>
int main(int argc,char *argv[])
{
char s1[10] = {'A','0','B','\0','C'};
int n;
n = strlen(s1);
printf("%d\n",n);
return 0;
}
/*
运行结果:
linux@ubuntu:~/C/day05$ gcc demo8.c -Wall
linux@ubuntu:~/C/day05$ ./a.out
3
//字符串是以'\0'结束,所以长度是到'前一个为止'
*/
5.2 字符串拷贝函数strcpy
格式:strcpy(字符数组1,字符串2)
功能:将字符串2,拷贝到字符数组1中去
反值:返回字符数组1的首地址
说明:字符数组1必须足够大,拷贝时'\0'一同拷贝
/*案例1:将makere字符串,复制到另一字符数组中,demo9*/
#include <stdio.h>
#include <string.h>
#define N 30
int main(int argc,char *argv[])
{
char src[] = "makere";
char dest[N];
strcpy(dest,src);
puts(src);
puts(dest);
return 0;
}
/*测试结果:
linux@ubuntu:~/C/day05$ gcc demo9.c -Wall
linux@ubuntu:~/C/day05$ ./a.out
makere
makere
*/
5.3 字符串连接函数strcat
格式:strcat(字符数组1,字符数组2)
功能:把字符数组2连到字符数组1后面
反值:返回字符数组1的首地址
说明:字符数组1必须足够大,连接前,两串均以'\0'结束;连接后,串1的'\0'取消,新串最后加'\0'
/*案例:将一个字符串连接到另一个字符串中 demo10*/
#include <stdio.h>
#include <string.h>
#define N 30
int main(int argc,char *argv[])
{
char src[N] = "xiaoqiang";
char dest[N] = ".com.cn";
puts(src);
puts(dest);
puts("------------------");
strcat(src,dest);
puts(src);
puts(dest);
return 0;
}
/*运行结果:
linux@ubuntu:~/C/day05$ gcc demo10.c -Wall
linux@ubuntu:~/C/day05$ ./a.out
xiaoqiang
.com.cn
------------------
xiaoqiang.com.cn
.com.cn
*/
5.4 字符串比较函数strcmp
格式:strcmp(字符串1,字符串2)
功能:比较俩个字符串
比较规则:对两串从左向右逐个字符比较(ASCII码),直到遇到不同字符或'\0'为止
返值:返回int型整数
若字符串1<字符串2,返回负整数
若字符串1>字符串2,返回正整数
若字符串1==字符串2,返回0
/*案例:比较俩字符串demo11*/
#include <stdio.h>
#include <string.h>
int main(int argc,char *argv[])
{
char s1[] = "abc";
char s2[] = "aba";
char s3[] = "abd";
char s4[] = "abc";
char s5[] = "ab";
char s6[] = "abcc";
printf("%-5sand %-5s %d\n",s1,s2,strcmp(s1,s2));
printf("%-5sand %-5s %d\n",s1,s3,strcmp(s1,s3));
printf("%-5sand %-5s %d\n",s1,s4,strcmp(s1,s4));
printf("%-5sand %-5s %d\n",s1,s5,strcmp(s1,s5));
printf("%-5sand %-5s %d\n",s1,s6,strcmp(s1,s6));
return 0;
}
/*运行结果:
linux@ubuntu:~/C/day05$ gcc demo11.c -Wall
linux@ubuntu:~/C/day05$ ./a.out
abc and aba 1
abc and abd -1
abc and abc 0
abc and ab 1
abc and abcc -1
*/
6.其他字符串函数
strncpy(p,p1,n)复制指定长度字符串
strncat(p,p1,n)附加指定长度字符串
strcasecmp(p,p1)忽略大小写比较字符串
strncmp(p,p1,n) 比较指定长度字符串
strchr(p,c) 在字符串中查找指定字符
strstr(p,p1) 查找字符串
/*测试案例 demo12*/
#include <stdio.h>
#include <string.h>
#define N 30
int main(int argc,char *argv[])
{
char src[] = "xiaoqiang";
char dest[N] = ".com.cn";
puts("------------strncpy----------");
puts(dest);
strncpy(dest,src,4);
puts(src);
puts(dest);
puts("--------------strncat----------");
strncat(dest,src,4);
puts(dest);
puts("------------strncmp,strcasecmp---------------");
char s1[] = "xiaoqiang";
char s2[] = "xiaotian";
char s3[] = "XIAOTIAN";
printf("s1:%s\ns2:%s\ns3:%s\n",s1,s2,s3);
printf("strcmp:%d\n",strcmp(s1,s2));
printf("strncmp:%d\n",strncmp(s1,s2,4));
printf("strcasecmp(s2,s3):%d\n",strcasecmp(s2,s3));
puts("-----------strchr-------");
char ch = 't';
printf("s2:%s\nh:'t'\nstrchr(s2,ch):%d\n",s2,strchr(s2,ch)-s2);
puts("----------strstr-------");
char s4[] = "tian";
printf("s2:%s\ns4:%s\nstrstr(s2,s4):%d\n",s2,s4,strstr(s2,s4)-s2);
return 0;
}
测试结果:
linux@ubuntu:~/C/day05$ gcc demo12.c -Wall
linux@ubuntu:~/C/day05$ ./a.out
------------strncpy----------
.com.cn
xiaoqiang
xiao.cn
--------------strncat----------
xiao.cnxiao
------------strncmp,strcasecmp---------------
s1:xiaoqiang
s2:xiaotian
s3:XIAOTIAN
strcmp:-1
strncmp:0
strcasecmp(s2,s3):0
-----------strchr-------
s2:xiaotian
h:'t'
strchr(s2,ch):4
----------strstr-------
s2:xiaotian
s4:tian
strstr(s2,s4):4
检查字符函数(位于ctype.h头文件中):
isalpha()检查是否为字母字符
isupper()检查是否为大写字母字符
islower()检查是否为小写字母字符
isdigit()检查是否为数字
toupper() 小写转大写
tolower() 大写转小写
/*测试案例1:输入一个字符,检查是否为字符,并检查是大写还是小写还是数字 demo13*/
#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);
}
else if(isdigit(ch))
printf("Digit:%c\n",ch);
else
printf("other:%c\n",ch);
getchar();
}
return 0;
}
/*测试结果:
linux@ubuntu:~/C/day05$ gcc demo13.c
linux@ubuntu:~/C/day05$ ./a.out
A
Upper:A
a
Lower:a
3
Digit:3
#
other:#
^C //ctrl+c结束
此案例是个死循环,故使用ctrl+c结束循环
*/
/*测试案例2:输入大写转小写,输入小写转大写 demo14*/
#include <stdio.h>
#include <ctype.h>
int main(int argc,char *argv[])
{
char ch;
while((ch = getchar()) != EOF){
if(isalpha(ch)){
if(isupper(ch))
ch = tolower(ch);
else
ch = toupper(ch);
printf("%c\n",ch);
}
}
return 0;
}
/*测试结果:
linux@ubuntu:~/C/day05$ gcc demo14.c -Wall
linux@ubuntu:~/C/day05$ ./a.out
abc
A
B
C
AAA
a
a
a
^C //ctrl+c结束
此案例是个死循环,故使用ctrl+c结束循环
*/