在同意作用域内,数组名不可以和其他变量或者数组同名 err:重名
数组的元素个数定义必须是整数,常量,或者是表达式常量,err:不能分配未知大小。
数组下标必须是整数,可以是变量,常量,表达式。 err:非整数
数组的大小一旦被定义不可以改变。
数组是一组在内存中连续依次排列的数据
int s[n]; 下标0开始 最大小标n-1
数组越界不检查,内存被修改,程序可能会崩溃 不err:越界内存数据未知,也可以利用越界这个特性做一些特殊骚操作。
例:
s[n-x] (n-x)<0
s[n+x] (n+x)>n
数组初始化,不初始化得到的会是未知值,也有可能编译器直接给赋值0
数组元素个数 sizeof(s)/sizeof(s[0])==sizeof(s)/sizeof(s的type)
数组占内存中的字节数 sizeof(s)
求第N个元素的地址 s[n]的地址= s的地址+sizeof(n)*sizeof(s的type)
数组地址==数组第0元素的地址==数组名 s[0]的地址=s的地址
数组当参数传 例:
int a (int s[],int b);//不需要填长度
n=0 s[n++]=6; s[1]==6; n==2;
数组作为函数参数,在函数内部改变了内容的话,会修改数组在外面的内容
多维数组-二维数组是特殊的一维数组,xy坐标,x行y列的map
int a[x][y]; x=3,y=2
int a[x][y]=
{
{1,2}
{3,4}
{5,6}
}
分布一:内存结构
a[0]== 1 |
a[1]== 2 |
a[2]== 3 |
a[3]== 4 |
a[4]== 5 |
a[(x*y)-1]== a[5]== 6 |
分布二:map,图表,坐标,矩阵
坐标 | y0列 | y1列 |
---|---|---|
x0 行 | a[0][0]== a[0]== 1 | a[0][1]== a[1]== 2 |
x1 行 | a[1][0]== a[2]== 3 | a[1][1]== a[3]== 4 |
x2 行 | a[2][0]== a[4]== 5 | a[2][1]== a[5]== 6 |
x=3,y=3
int a[][3] = {{0},{1},{2}}; a[1][2]==?
int a[][3] = {{0,0,0},{1,0,0},{2,0,0}}; a[1][2]==a[1*3+2]==a[5]==0
二维数组下标转一维数组 a[1][2]== a[1*y+2]==a[3+2]=a[5]
多维数组-三维数组
int a[2][3][4]=
{
{
{1,2,3,4},
{5,6,7,8},
{1,2,3,4}
},
{
{1,2,3,4},
{5,6,7,8},
{1,2,3,4}
}
}
字符数组
- 除了在定义时初始化,只能一个元素一个元素的赋值。
- 字符数组中的全部内容输出也只能一个一个的输出。
- 数组大小定义以后不可以更改大小
//第一种
char c[9];
//第二种
char c[]={'s','r','g','g','5','t','t','t','j'};
//第三种
char c[9]={'s','r','g','g','5','t','t','t','j'};
//第四种
char c[9];
c[0]='s';
c[1]='r';
c[2]='g';
c[3]='g';
c[4]='5';
c[5]='t';
c[6]='t';
c[7]='t';
c[8]='j';
c[0] | c[1] | c[2] | c[3] | c[4] | c[5] | c[6] | c[7] | c[8] |
---|---|---|---|---|---|---|---|---|
s | r | g | g | 5 | t | t | t | j |
字符串
- 字符串是基于字符数组的,区别在于字符串末尾以’\0’作为结束符
- '\0’代表ASCII码为0的字符,是一个空操作符
- 字符串输入可以用scanf("%s",c); scanf("%c",c[i]);
- 当格式符为“%s”时,scanf()函数的地址列表是字符数组的名字,并且无需加地址符&。
- 字符串输出可以用printf("%s",c); printf("%c",c[i]);
- 利用 %s 输入输出字符串,字符数组要不小于字符串的个数,否则出错。
- 错误:Run-Time Check Failure #2 - Stack around the variable ‘str2’ was corrupted. 出现了
- 字符串初始化时,字符数组长度可以大于字符串长度
//第一种
char c[10]="srgg5tttj";
//第二种
char c[10]={'s','r','g','g','5','t','t','t','j','\0'};
//第三种
char c[10]={'s','r','g','g','5','t','t','t','j','\0'};
//第四种
char c[10];
c[0]='s';
c[1]='r';
c[2]='g';
c[3]='g';
c[4]='5';
c[5]='t';
c[6]='t';
c[7]='t';
c[8]='j';
c[9]='\0';
//第五种
char c[10];
//第六种
char c[100]="sxsa";
//第七种
char c[][100]={"sxsa","dfsdf","sdfds","54sdc"};
//第八种
//第七种
char c[100]={"sxsa","dfsdf","sdfds","54sdc"};
c[0] | c[1] | c[2] | c[3] | c[4] | c[5] | c[6] | c[7] | c[8] | c[9] |
---|---|---|---|---|---|---|---|---|---|
s | r | g | g | 5 | t | t | t | j | ‘\0’ |
使用函数
- stdio.h
- getchar–>字符输入函数
- putchar–>字符输出函数
- scanf–>字符,字符数组,字符串输入函数
- printf–>字符,字符数组,字符串输出函数
- gets–>字符数组,字符串输入函数
- puts–>字符数组,字符串输出函数
- string.h
- strlen
- strcpy
strcpy
- 用于将字符串2复制到字符数组1中
问题:字符串能不能使用赋值语句?
当左值,还是仅仅是数组名赋值。自行了解左值右值的概念。
strlen
- 测试字符串实际长度,返回值是字符串中字符的个数不包含(’\0’)
int main()
{
int i;
char str1[20];
char str2[20];
gets(str1);
gets(str2);
for (i=0;str2[i]!='\0';i++);
printf("%s:%d\n",str1,strlen(str1));
printf("%s:%d\n",str2,i);
printf("%s:%d\n","i like C",strlen("i like C"));
system("pause");
return 0;
}
//函数只管读取到字符串内不包含'\0'的长度,并不管这个字符串长度是否超过这个字符数组。
模拟strlen函数
int string_len1(char str[])
{
int i=0;
while(str[i]!='\0')
{
i++;
}
return i;
}
int main()
{
int i;
char str1[20];
char str2[20];
gets(str1);
gets(str2);
/*
for (i=0;str2[i]!='\0';i++);
放在这里会覆盖内存中的数据,导致了str1求len结果出错,以后要注意一下内存溢出的问题,和相关内存结构的问题
思考:如果是一个溢出bug,怎么使其后面的值一部分不被覆盖。
*/
printf("%s:%d\n",str1, string_len1(str1));
for (i=0;str2[i]!='\0';i++);
printf("%s:%d\n",str2,i);
printf("%s:%d\n","i like C", string_len1("i like C"));
system("pause");
return 0;
}
gets
- 作用:将一个字符串输入到字符数组中
- gets(字符数组名);
- 读入一个字符串后,系统自动在字符串后加上一个字符串结束符’\0’
- 只能一次输入一个字符串
- 可以读入包含空格和TAB的全部字符,遇到回车为止
int main()
{
char str1[20],str2[20];
gets(str1);
scanf("%s",str2);
printf("str1:%s\n",str1);
printf("str2:%s\n",str2);
system("pause");
return 0;
}
puts
- 用于整个字符串的输出
- puts(字符数组名);或puts(字符串);
- 可以输出转义字符
- 一次只能输出一个字符
- 输出字符串后自动换行
int main()
{
char str1[]="student",str2[]="teacher";
puts(str1);
puts(str2);
printf("%s",str1);
printf("%s",str2);
printf("\n%s\n%s",str1,str2);
system("pause");
return 0;
}
getchar
- 作用从输入设备读取一个字符
- 没有参数
- 一次只接受一个字符
- 可以接收回车字符
- 接收的字符可以不赋值给任何变量
char a;
a=getchar();
scanf("%c",&a)
//两个写法等价
putchar
- 作用是讲一个字符输出到输出设备
- 可以输出字符型变量,整型变量,字符型常量,控制字符,转义字符
- 一次只能输出一个字符
char c='c';
putchar(a);
printf("%c",a);
int main()
{
char str1[6], str2[10];
int i;
for (i = 0; i < 5; i++)
{
scanf("%c", &str1[i]);
}
str1[5] = '\0';
scanf("%s", str2);
printf("%s\r\n%s\r\n", str1, str2);
system("pause");
return 0;
}