C语言day06
【1】数组
1》概念:
具有一定顺序的若干变量的集合
2》定义格式:
存储类型 数据类型 数组名[元素的个数]
例:
int arr[5]; //定义了一个数组arr,在内存空间中开辟了5个空间来储值
在数组中保存的每一条数据都叫(元素)变量
数组名:代表数组的首地址(地址常量);数组名不能被重新赋值,不能为左值(等号左边的值)
int arr[5] = {1,2,3,4,5};
3》数组的访问:
数组名[下标]
arr[0]; //1
arr[2]; //3
arr[4]; //5
访问第n个元素就是arr[n-1];
4》修改数组内元素
数组名[下标] = 新值
arr[3] = 100; //把100赋值给arr[3]
5》数组越界
定义时数组越界:
int arr[3] = {1,2,3,4}; //4就是定义时的数组越界
定义时只开辟了3个空间,但是定义初始值时却是4个值,属于数组越界
访问时数组越界:
int arr[3] = {1,2,3};
printf("%d",a[3]); //a[3]就是访问时的数组越界
定义时开辟了3个空间,并初始化了值,但是访问时访问到了开辟的3个空间外的空间了,属于数组越界
注意:
(1)数据类型相同---定义int 类型数组,数组中每一个元素都是int类型
(2)内存连续
(3)数组名[下标]---变量名 数组内元素-----变量的值
(4)数组名的命名要符合标识符的命名规范
(5)在同一个函数中,变量名和数组名不能同名
int a[3];
int a; //定义了一个变量a和数组a,同名会产生错误
(6)数组的下标从零开始,最后一个元素的下标是n-1
(7)数组名的地址常量
6》初始化
(1)全部初始化
int a[3] = {1,2,3};
(2)未初始化
int a[3]; //未初始化的话,就是随机值,后续赋值只能挨个元素进行赋值
a[0] = 1;
a[1] = 2;
a[2] = 3;
(3)部分初始化
int a[5] = {1,2}; //这样定义前两个被初始化为1,2 剩下没初始化的会自动赋值初始化为0
定义空数组:
- int a[3]={0,0,0};
- int a[3]={0};
- int a[3]={};
7》引用
(1)先定义后引用
(2)每一次访问只能访问一个值a[i],如果想引用数组中所有的元素可以选择遍历(使用循环)
(3)引用时要防止数组的越界,但是编译器有时候不会报错但是会报警告
(4)对于数组中的每一个元素的地址的打印使用%p格式
(5)内存分配
8》数组的遍历
输入元素保存到数组中,并输出数组中的元素
练习:
对数组内元素进行求和
9》数组的大小
int a[3]; //开辟12个字节空间
(1)数据类型大大小 * 元素的个数
(2)sizeof(数组名)
计算元素个数:
sizeof(数组名) / sizeof(数组数据类型)
练习:
计算斐波那契数列前15项并逆序输出
1 1 2 3 5 8 13 21 .....
int a[15];
int i ;
a[0] = a[1] = 1;
printf("%d %d ",a[0],a[1]);
for(i = 2;i <= 14;i++){
a[i] = a[i-1] + a[i-2];
printf("%d ",a[i]);
}
printf("\n");
/*for(i =14;i >= 0;i--){
printf("%d ",a[i]);
}*/
int *p = a;
int *q = &a[14];
int t;
while(p < q){
t = *p;
*p = *q;
*q = t;
p++;
q--;
}
for(i = 0;i < 14;i++){
printf("%d ",a[i]);
}
printf("\n");
10》清零函数
bzero
需要一个头文件 #include <strings.h>
void bzero(void *s,size_t n);
功能:将数组内的内存空间设置为0;
参数:s:要清空的数组的首地址
n: 数组的大小(字节)
返回值:无
memset
需要一个头文件 #include <string.h>
void *memset(void *s,int c,size_t n);
功能:将数组的内存空间设置为某一个值
参数:s:要清空数组的首地址
c:要设置的值(只能设置0,设置别的值得不到想要的值)
n:数组的大小(字节)
返回值:清空的数组的首地址
【2】字符数组
1》概念
字符数组的里面存放的都是字符 存放的就是字符串
2》格式
char str[3] = {'a' , 'b' , 'c'}; //逐个字符赋值
char str[] = {'a','b','c'}; //逐个字符赋值 没定义数组的大小,则后面赋值多少个字符就开辟多少个空间 数组大小:3 元素个数:3
char str[] = "hello"; //使用字符串赋值 数组大小:6 因为系统会自动在字符串后面加\0
char str[32] = "hello"; //使用字符串赋值 数组大小:32
注意:使用字符串赋值时会省略后面的\0 可能会产生数组越界,所以一般不会在定义时就写大小。
3》字符数组的输入输出
(1)for循环 格式:%c
(2)直接使用%s输入输出(空格和回车都是结束的标志)
(3)使用%[^\n]输入输出,这个方法不会因为空格和回车而结束,直到遇到\n结束
%[^\n]的意思就是 : 除\n以外都是符合的格式
练习:
在终端输入大写字母、小写字母、空格、数字,分别在终端输出他们的个数
定义字符数组的时候要记得初始化,char str[20] = {};如果不初始化的话,都是随机值
4》gets输入函数、puts输出函数
头文件 #include <stdio.h>
输入:gets
char *gets(char *s)
功能:从终端输入一个字符串
参数:s:字符数组的首地址(字符串保存位置)
返回值:字符数组的首地址
注意:不关注数组越界的问题
输出:puts
int puts(const char *s);
功能:向终端输出一个字符串
参数:字符串的首地址
返回值:输出字符的个数
5》计算字符串的实际长度
(1)循环
(2)strlen
#include <stdio.h>
size_t strlen(const char *s);
功能:计算字符串的实际长度(不包含\0)
参数:要计算的字符串的首地址
返回值:字符串的实际个数
6》sizeof和strlen的区别
(1)sizeof计算开辟内存空间的大小 strlen 计算字符串的长度
(2)sizeof是关键字 strlen是函数
(3)sizeof 计算时会计算\0 strlen不会
练习:
实现字符串的大小写转换