数组 构造数据类型
数组学习:定义 初始化 应用
1、数组的定义:
格式: <存储类型> 数据类型 数组名称[整数表达式];
eg: int a[10];
含义: 定义一个数据类型为int的数组名称叫a,该数组中默认有10个数据成员。
注意:
1、存储类型可以省略,默认是auto,其他可以自定义。
2、数据类型可以是基本数据类型也可以是构造数据类型。
3、数组名称必须符合C 语言命名规范。
4、整数表达式,要求必须是正整数,不能是负值或者浮点数
特征:
1、数组的[]中的整数称为 下标,表示数组的元素个数。
eg: int a[10]; ===>10是下标,一共10个int元素。
而且数组默认下标从0 开始计数。10 范围 0~9
需要访问数组成员用 a[n] ==>n 在0~9 不能是10
2、每个数组元素默认在内存地址关系上是连续的,但是默认的地址连续是以数据类型为单位。
char a[10] ; a[1] a[2] a[3]…a[9];
地址以单字节连续
int b[10]; b[1] b[2] b[3]…b[10];
地址以4字节连续。
3、数组定义的存储类型决定了数据的初始值。
如果是auto在栈区,可能数据是随机值。
如果是static在常量区,数据一定是0;
数组的初始化
数组的初始化:====>定义过程中赋值
1. 不初始化,只定义不初始化,一般用于static或者全局变量定义的数组。
2. 部分初始化,只将数组中部分元素赋值
eg:int a[10] = {1,2,3};
⇒ a[0] == 1 a[1] 2 a[2] 3;
⇒ 其他的可能是随机值
3. 全部初始化,将数组的每个元素都赋值
eg: int a[5] ={5,6,7,8,9};
⇒ a[0] = 5,a[1]= 6,a[2]= 7,
a[3]= 8,a[4]= 9;
4. 默认初始化,定义的时候一次性赋值。
eg: int a[10] = {0};
只能用{0} 初始化所有数据为0。
5. 不定长初始化,数组的长度不确定。
eg: int a[] ={1,2,3}; //不定长初始化
int a[]; ///错误不能定义空数组
int a[] ={0}; //只有一个元素,没意义
不定长初始化数组大小根据初始化值的个数决定。
数组的应用
数组的应用:
1、数组赋值
1.1 直接赋值:
int a[10]={0}; ///先定义数组
a[3] = 88; ///数组赋值
1.2 遍历赋值:
int a[10] ={0};
for(i=0;i<10;i++)
{
a[i]=7; ///一种
scanf("%d",&a[i]); //另一种
}
2、数组遍历
2.1 数组的顺序遍历
for(i=0;i<n;i++)
{
printf(“xxx”,xxx);
}
2.2 数组的排序遍历
2.2.1 冒泡排序
核心算法:
for(i=0;i<n-1;i++)
{
for(j=0;j<n-i-1;j++)
{
if(a[j] > a[j+1])
{
t = a[j];
a[j]= a[j+1];
a[j+1]= t;
}
}
}
for(i=0;i<n;i++)
printf("%d ",a[i]);
2.2.2 选择排序
核心算法
for(i=0;i<n;i++)
{
min = i;
for(j=i+1;j<n;j++)
{
if(a[min] > a[j])
min =j;
}
if(min != i)
{
t = a[i];
a[i] = a[min];
a[min] = t;
}
}
for(i=0;i<n;i++)
printf("%d ",a[i]);
随机函数
随机函数rand
功能:
参数:
返回值:
1、产生的是0~100之内的随机数
sum = rand() %100;
2、随机产生5个3位随机数
sum = rand() %900 +100;[100~999]
srand();随机种子
功能:
参数:
返回值:
注意:srand()只能使用一次,不能放置循环中
#include <stdio.h>
#include <stdlib.h>
int miain(void)
{
int i = 0;
int sum = 0;
for(i=0;i<5;i++)
{
sum = rand();
}
return 0;
}
字符数组
字符数组 ===》 字符串 ===》指针
定义: <存储类型> 数据类型 数组名称[整数表达式];
eg: char c[10];
初始化:
部分初始化:char c[10] ={‘n’,‘i’,‘h’,‘a’,‘o’};
char c[10] ={ “hello”};
全部初始化:char c[5] ={‘w’,‘o’,‘h’,‘a’,‘o’};
用字符串初始化:char c[] =“nihao”;
注意:
char c[10]; c= “nihao”; //错误
c[0] =‘n’;
c[1] =‘i’;
格式化输入输出对应与字符数组:
1、输入: scanf("%c", &c[n]); ///n是字符数组的某个下标
scanf("%s", c); ///以字符串形式存储到c字符数组
2、输出: printf("%c \n", c[n]); ///输出字符数组中下标为n的字符
printf("%s \n",c); ///以数组形式将字符串输出。
字符串与字符数组的区别和联系;
C 语言中没有一个用于表示字符串的关键字。
C 语言的字符串用c的字符数组变形而成。==>末尾加’\0’;
字符串比字符数组多一个’\0’;
联系:都是以数组形式存储数据。字符之间地址连续,同时可以用下标访问。
同样的数据如果以字符数组和字符串形式存储
大小会有差别,字符串比字符数组大一个字节存储’\0’;
考虑:如何编写代码计算一个字符数组中字符串的有效长度?
字符串长度计算函数: strlen()
#include <string.h> ///c中与字符串相关操作都在文件中声明
size_t strlen(const char *s);
功能:计算参数指定的字符串的有效字符个数。
参数:s 可以是数组名称,也可以是指针表示的是一个字符串开始
返回值:成功 返回字符串的长度
字符串常用操作函数:
strcpy();
strcmp();
strcat();
strlen();
1、strcpy() <==== 字符串不能直接用数组名称赋值。
char c[10];
c = “nihao”; ///错误
但是: strcpy(c,“nihao”);//正确的
char *strcpy(char *dest, const char *src);
功能:将指定的数据src内容拷贝到dest目标内存区。
参数:dest存储数据的目标内存
src 数据的源内存
返回值:成功 返回指向dest的指针
失败 NULL;
2、strcmp() <==== 字符串数据比较过程
int strcmp(const char *s1, const char *s2);
功能:将指定的s1字符串与指定的s2字符串比较如果相等则返回0 否则返回非0
参数:s1 字符串1
s2 字符串2
返回值:成功 相等 返回0
不相等 返回非0;
返回值有两种:一种为1 -1 则为两个字符不相同时,s1大于s2时为1,s1小于s2时为-1;
一种为具体的数值,则为两个字符的ascii码的差值。
3、strcat() ===>字符串串接
char *strcat(char *dest, const char *src);
功能:将src所在的字符串串接到dest的字符串末尾形成一个新的长字符串。
参数:dest 目标字符串
src 源字符串
返回值:成功 返回指向目标的字符串
失败 NULL
二维数组
二维数组:
前面讲解的是数组,还可以声明"数组的数组",即大家所说的多维
数组。
1. 二维数组的声明:
int [10][10];
有上面声明的意义是指声明了一个int型的数组的数组,数组有10个元素,每一个元素又是包含10个int型元素的数组。
2. 多维数组的数组元素的访问
多层循环
3. 二位数组的初始化:
默认初始化int a[10][10]={0};
不初始化:全局变量和static定义的二维数组
部分初始化:
int a[10][10]={{10,9,6,8},{6,5,4,8}};
int a[10][10]={{10,9,6,8},{6,5,4,8}};//错误
全部初始化:
int a[5][5]={{10,9,6,8,7},
{6,5,4,8,6},
{5,4,3,2,1},
{6,8,7,9,1},
{4,5,6,7,8}};
不定长初始化
int a[][10]={{10,9,6,8},{6,5,4,8}};
多维数组其实就是“数组的数组”
int array[3][4];
-
array 的类型为 “int的数组(元素个数4)的数组(元素个数3)”。
-
在表达式中数组可以被解读成指针。array的类型为:
指向int的数组(元素个数4)的指针。int *array[3] -
array[i] 等价于 *(array + i)。
*(array + i) 的类型就是 “指向int的数组(元素个数4)”。
-
(*(array + i))[j] 和 (((array + i)) + j) 是相等的。
(*(array + i))[j] 就是 “对指向int的指针加上j后得到的地址
上的内容”,其类型为int。
多维数组的传参:
int array[3][4];
int 的数组(元素个数4)的数组(元素个数3)
数组可以解释成指针,所以可以向函数传递指向int的数组(元素个数4)的指针
参数说白了就是"指向数组的指针"。
也就是说接收这个参数的函数的原型为:
void func(int *p[4]);
或void func(int p[3][4]);
或void func(int p[][4]);
一般地,声明N维数组的指针时,除了最左边的方括号可以留空之外,其他都需要填写数值。