一维数组
声明数组时要遵循以下规则
1.数组名的命令规则和变量名的相同,即遵循标识符命名规则。
2.在定义数组时,需要指定数组中元素的个数,方括号中的常量表达式用来表示元素的个数,即数组长度。
3.常量表达中可以包含常量和符号常量,但不能包含变量。也就是说,C语言不允许对数组的大小做动态定义,即数组的大小依赖于程序运行过程中变量的值。
一维数组的存储及函数传递
# include<stdlib.h>
# include<stdio.h>
//一维数组的传递,数组长度无法传递给子函数
//C语言的函数调用方式是值传
//其实变量b是指针类型
void print(int b[], int len) {
int i;
for (i = 0; i < len; ++i) {
printf("%3d",b[i]);
}
b[4] = 20;//在子函数中修改数组元素
printf("\n");
}
//数组越界
//一维数组的传递
# define N 5
int main() {
int j = 10;
int a[5] = { 1,2,3,4,5 };//定义数组时,数组长度必须固定
//实际数组名中存储的是数组的首地址
int i = 3;
a[5] = 20;//越界访问
a[6] = 21;
a[7] = 22;//越界访问会造成数据异常
print(a,5);
printf("a[4]=%d\n",a[4]);//a[4]发生改变
system("pause");
}
二维数组
二维数组的存储与传递
# include<stdlib.h>
# include<stdio.h>
//二维数组的首地址,赋值给b
//行不能传递过去,列一定要写
void print(int b[][4],int row) {
int i, j;
for (i = 0; i < row; ++i) {
for (j = 0; j < sizeof(b[0]) / sizeof(int); j++) {
printf("%3d",b[i][j]);
}
printf("\n");
}
}
//二维数组的存储结构
//二维数组的传递
int main() {
int a[3][4] = { 1,2,3,4,5,6,7,8,9,11,13,15 };
float b[4] = { 1,2,3,4 };
int c[3][4] = { {1}, {5,9} };//可以只对部分元素进行初始化
print(a, 3);
printf("a[2][3]=%d\n",a[2][3]);//打印最后面的一个元素
system("pause");
return 0;
}
字符数组
字符数组初始化及传递
# include<stdio.h>
# include<stdlib.h>
void print(char c[]) {
int i = 0;
while (c[i]) {
printf("%c",c[i]);
i++;
}
printf("\n");
}
//字符数组存储字符串,必须存储结束符'\0'
//scanf读取字符串时使用%s
int main() {
char c[5] = { 'h','e','l','l','o' };
char d[5] = "how";
printf("%s-----------%s",c,d);//会发现打很多“烫”字
//这是因为printf通过%s打印字符串时,原理是依次输出每个字符,当读到结束符'\0'时,结束打印
//scanf通过%s读取字符串,对c和d分别输入"are"和"you"(中间加一个空格),scanf在使用%s读取字符串时,会忽略空格和驾车.
scanf("%s%s",c,d);
printf("%s---------%s",c,d);
print(c);
system("pause");
return 0;
}
scanf通过%s读取字符串,对c和d分别输入"are"和"you"(中间加一个空格),scanf在使用%s读取字符串时,会忽略空格和回车.
gets函数与puts函数
gets函数类似于scanf函数,用于读取标准输入。前面我们已经知道scanf函数在读取字符串时遇到空格就认为读取结束,所以当输入的字符串存在空格时,我们需要使用gets函数进行读取。
gets函数的格式如下:
char *gets(char * str)
gets函数从STDIN(标准输入)读取字符并把它们加载到str(字符串)中,直到遇到换行符(’\n’)或到达EOF。当gets遇到‘\n’后,不存储’\n’,而是将其翻译为空字符’\0’
puts函数类似于printf函数,用于输出标准输出。puts函数的格式如下
int puts(char *str)
函数puts把str(字符串)写入标准输出。puts执行成功返回非负值,执行失败时返回EOF。相对于printf函数,puts只能用于输出字符串,同时多打印一个换行符。
# include<stdio.h>
# include<stdlib.h>
//gets和puts都是不安全的,可能会造成栈异常
int main() {
char c[50];
gets(c);
printf("%s\n",c);//puts(c)等价于printf("%s\n",c),puts多了一个打印换行
system("pause");
}
# include<stdio.h>
# include<stdlib.h>
int main() {
char c[50];
//gets的返回值是一个字符指针
//输入一行打印一行
while (gets(c)!=NULL) {
puts(c);
}
system("pause");
}
str系列字符串操作函数
strncpy
char strncpy(charto,const char *from,size_t count);
功能:将字符串from中至多count个字符复制到字符串to中。如果字符串from的长度小于count,其余部分用’\0’填补。返回处理完成的字符串。
strncmp
strncat
# include<stdio.h>
# include<stdlib.h>
# include<string.h>
int main() {
char c[50];
char d[50];
while (gets(c)!=NULL) {
memset(d, 0, sizeof(d));//把从d开始的接下来的每一个字节都填为0
strncpy(d, c, 7);
puts(d);
printf("cmp result=%d\n",strncmp(d,"李宁",2));
strncat(d,"牛牛牛",2);
puts(d);
}
system("pause");
}
mem系列操作函数
虽然放到字符数组这一节,但是我们的mem系列函数是任何数组都可以进行操作的,无论是字符数组,还是整型数组,浮点型数组,或者后面我们讲的结构体数组。当需要对一个数组进行全部置位零时,我们需要使用到memset.
# include<stdio.h>
# include<stdlib.h>
# include<string.h>
//strcpy不能用于整型数组,因为在copy过程中,遇到'\0'就结束copy
//strcpy遇到'\0'就结束复制
int main() {
int a[5] = { 99999,2,3,4,5 };
int b[5];
memcpy(b, a, sizeof(a));
}