目录
一.数组的定义
数组:所谓数组是指一组具有相同数据类型的数据的有序集合。
某班学生的学习成绩,一行文字,一个矩阵等数据的特点如下:
(1)具有相同的数据类型。
(2)使用过程中需要保留原始数据。
C语言为了方便操作,这些数据提供了一种构造数据类型——数组
一维数组的定义格式:
类型说明符 数组名 [常量表达式];
例如:
int a[10];//定义一个整型数组,数组名为a,它有10个元素
声明数组时要遵循以下规则:
(1)数组名的命名规则和变量名的相同,即遵循标识符命名规则
(2)在定义数组时需要指定数组中的元素的个数,方括号中的常量表达式用来表示元素的个数,即数组长度。
(3)常量表达式中可以包含常量和符号常量,但不能包含变量,也就是说,C语言不允许对数组的大小作动态定义,即数组的大小不依赖于程序运行过程中变量的值。
以下是错误的声明示范(最新的c标准支持,但最好不要这样写。)
int n;
scanf("%d",&n);
int a[n];
二.一维数组在内存中的存储
一维数组的初始化方法
(1)在定义数组时对数组元素赋初值
int a[10]={1,2,3,4,5,6,7,8,9};
不能写成:int a[10]; a[10]={1,2,3,4,5,6,7,8,9};
(2)可以只给一部分元素赋值
int a[10]={0,1,2,3,4};
定义a数组有十个元素,但花括号内只提供五个初值,这表示只给前五个元素赋初值,后五个元素的值为0。
(3)如果要是一个数组中全部元素的值为零
int a[10]={0};
(4)在对全部数组元赋初值时,由于数据的个数已经确定,因此可以不指定数组的长度
int a[]={1,2,3,4,5};
三.数组的访问越界
#include <stdio.h>
//数组越界
int main() {
int a[5]={1,2,3,4,5};
int j=20;
int i=10;
a[5]=6;//越界访问
a[6]=7;//越界访问会造成数据异常
printf("i=%d\n",i);//i发生变化
return 0;
}
运行结果
数组另一个值得关注的地方是,编译器并不检查程序对数组下标的引用是否在数组的合法范围内。
四.数组的传递
#include <stdio.h>
//一位数组的传递,数组长度无法传递给子函数
//c语言的函数调用方法是值传递
void print(int a[],int len){
int i;
for(i=0;i<len;i++){
printf("%3d",a[i]);
}
a[4]=20;//在子函数中修改数组元素
printf("\n");
}
int main() {
int a[5]={1,2,3,4,5};//定义数组时,数组长度必须是固定的
print(a,5);
printf("a[4]=%d\n",a[4]);
return 0;
}
这是因为一维数组在传递时,其长度是传递不过去的,所以我们通过 len 来传递数组中的元素个数
五.字符数组
1.字符数组的初始化以及输出
#include <stdio.h>
int main() {
char c[10]="Iamhappy";//使用这种方式进行初始化
char a[6]="hello";//注意:不能用a[5],否则'\0'访问越界
char b[5]={'h','e','l','l','o'};//这是错误的初始化,没有结束符,输出会出现乱码
printf("%s\n",c);//可用%s输出字符数组,不需要for循环
printf("%s\n",b);//输出出现乱码或不对
return 0;
}
2.scanf读取字符串
#include <stdio.h>
//scanf读取字符串,会自动往字符数组中放结束符
int main() {
char c[10];
scanf("%s",c);//不需要取地址,字符数组名c中存储了数组的起始地址
printf("%s\n",c);
return 0;
}
会发现are没有输出,如果要输出两个字符数组,该怎么写
#include <stdio.h>
//scanf读取字符串,会自动往字符数组中放结束符
//要读取两个字符数组,就先定义两个字符数组
int main() {
char c[10];
char a[10];
scanf("%s%s",c,a);//在scanf里面%s会忽略空格和回车(这一点与%d和%f类似)
printf("%s%s\n",c,a);
return 0;
}
六.gets和puts函数
gets 函数类似于 scanf 函数,用于读取标准输入。前面我们已经知道 scanf 函数在读取字 符串时遇到空格就认为读取结束,所以当输入的字符串存在空格时,我们需要使用 gets 函数进行读取。
gets 函数从 STDIN(标准输入)读取字符并把它们加载到 str(字符串)中,直到遇到换 行符(\n)。如下例所示,执行后,我们输入"how are you",共 11 个字符,可以看到 gets 会 读取空格,同时可以看到我们并未给数组进行初始化赋值,但是最后有'\0',这是因为 gets 遇 到\n 后,不会存储\n,而是将其翻译为空字符'\0'。
函数 puts 把 str(字符串)写入 STDOU(标准输出)。puts 会将数组 c 中存储的"how are you"字符串打印到屏幕上,同时打印换行,相对于 printf 函数,puts 只能用于输出字符串,同 时多打印一个换行符,等价于 printf(“%s\n”,c)。
#include <stdio.h>
int main() {
char c[20];
gets(c);//gets中放入字符数组的数组名
printf("%s\n",c);
return 0;
}
#include <stdio.h>
int main() {
char c[20];
gets(c);//gets中放入字符数组的数组名
puts(c);//等价于printf("%s\n",c);puts内放的参数是字符数组名
return 0;
}
七.str 系列字符串操作函数
strlen 函数用于统 计字符串长度,strcpy 函数用于将某个字符串复制到字符数组中,strcmp 函数用于比较两个字 符串的大小,strcat 函数用于将两个字符串连接到一起。
strcpy 函数用来将字符串中的字符逐个地赋值给目标字符数组。strcat 函数用来将一个字符串接到另外一个字符串的末尾。
#include <stdio.h>
#include <string.h>
int main() {
int len;//存储字符串长度
char c[20];
char d[100]="world";
gets(c);
puts(c);
len=strlen(c);//strlen("hello")统计字符串长度
printf("len=%d\n",len);
strcat(c,d);//把d中的字符串拼接到c中 strcat(c,"world")
puts(c);
strcpy(d,c);//把c中的字符复制给d strcpy(d,"hello")
puts(d);
printf("c?d=%d\n",strcmp(c,"how"));//strcmp(c,d)
//strcmp 函数用于比较两个字符串的大小
return 0;
}
#include <stdio.h>
#include <string.h>
int main() {
int len;//存储字符串长度
char c[20];
char d[100]="world";
gets(c);
puts(c);
len=strlen(c);//统计字符串长度
printf("len=%d\n",len);
strcat(c,"world");
puts(c);
strcpy(d,"hello");
puts(d);
printf("c?d=%d\n",strcmp(c,"how"));
//strcmp 函数用于比较两个字符串的大小
return 0;
}
例题:
#include <stdio.h>
//读取一个字符串,字符串可能含有空格,将字符串逆转,原来的字符串与逆转后字符串相同,
// 输出0,原字符串小于逆转后字符串输出-1,大于逆转后字符串输出1。
// 例如输入 hello,逆转后的字符串为 olleh,因为hello 小于 olleh,所以输出-1
//注意最后的判断一定要这么写,因为strcmp标准C中并不是返回-1和1,而是负值和正值
#include <string.h>
//字符串反转,
int main() {
char c[100];//原字符串
char d[100]={0};//反转字符串,初始化的目的是为了d有结束符
gets(c);
int i,j;
for(i=0,j= strlen(c)-1;i< strlen(c);i++,j--){
d[j]=c[i];
}//或者j>=0
int result=strcmp(c,d);
if(result<0){
printf("%d\n",-1);
} else if(result>0){
printf("%d\n",1);
} else{
printf("%d\n",0);
}
return 0;
}