数组
- 数组通常理解成为连续的存储单元的集合,但并不仅仅如此,数组还应该是
<index,value>
二元组有限index
和value
之间的映射; - 对于数组的抽象类型来说,还应该支持两个标准操作:取值和赋值;
C
语言的数组是这样定义的
int list[5];
int list *plist[5];
int list[5]
:表示的含义是5
个整型值组成的数组,int *plist[5]
表示的是5
个整型指针组成的数组;- 由于数组存储数据的空间是连续的,所以是可以通过指针的移动来访问各个不同的元素的,更一般的形式是通过
*(&a+i)
,其中a
表示的是数组元素的首地址,i
表示的是需要访问第几个元素,其实本质上应该是*(&a+i*sizeof(int))
的形式来访问元素的,只是编译器帮我们做了这个工作; - 关于指针的操作有两个运算符:
&
:这个运算符是用来获取某个对象的地址的;*
:解引用运算符这个运算符的作用是用来取得地址空间里面的值的;
- 对于一维数组首先来进行简单的元素访问操作;
#include<stdio.h>
#include<stdlib.h>
//数组的首地址其实就是数组名称,不需要取地址符号;
void print(int array[],int size){
if(array==NULL||size==0)
exit;
for(int i=0;i<size;++i){
//array+i得到的是地址值,所以需要解引用符号;
printf("%d ",*(array+i));
}
}
int main()
{
int array[5] = {1, 2, 3, 4, 5};
int k = *(&array[0]+1);
printf("array[1] is: %d\n", k);
k = *(&array[0]+1*sizeof(int));
printf("array[1] is: %d\n", k);
//sizeof运算符用来获取数据类型的长度;
print(array,sizeof(array)/sizeof(int));
}
数组空间的内存大概:
- 1.每个数据存储单元之间相差四个字节,恰好是一个整型数据单元的长度;
- 在访问数组里面的数据时,地址空间应该从
0
而不是1
开始进行访问; - 上面的代码也是可以进行数组的赋值操作的,上面使用的是指针的方式进行访问;
- 数组支持下标访问方式
array[i]
,在进行下标访问时,其实进行的是上面的提到的转换过程;
数组的动态存重点内容储空间
- 补充一点关于内存的一点知识:
- 1.
C
语言在进行编译后,通过三种方式使用内存非别是: - 2.静态内存/全局内存,全局变量使用这部分空间,这些空间在程序运行时开始分配,并且在程序终止时会被释放;
- 3.自动内存:在函数体内部声明,并且在函数被调时才会创建,生命周期仅限于当前函数作用域;
- 4.最后一种就是动态内存了:动态内存堆上面进行分配;也就是一会要使用的,这部分知识我回详细总结的;
- 1.
- 数组分配动态内存需要使用
void *malloc(size_t size)
和void free(void *ptr);
函数,其实相关的函数还包括void *calloc(size_t nmemb, size_t size);
,void *realloc(void *ptr, size_t size);
,暂时先介绍这两个; - 在使用
malloc
分配内存空间时,一定需要检查内存空间是否成功分配; - 这里补充一个关于
malloc
分配内存进行异常处理宏
#define MALLOC(p,s)\
if(!(p)=malloc(s)){\
sprintf(stderr,"Insufficient memory");\
exit;\
}\
- 按照前面介绍的,在进行动态内存分配的过程中,必须进行检测是否分配成功;
#include<stdio.h>
#include<stdlib.h>
#define MALLOC(p,s)\
if(!((p)=malloc(s))){\
fprintf(stderr,"Insufficient memory");\
exit(EXIT_FAILURE); \
}
int main(){
int n;
int *plist;
printf("Enter the number of numbers to generate: ");
scanf("%d",&n);
if(n<1){
fprintf(stderr,"Improper value of n\n");
exit(EXIT_FAILURE);
}
MALLOC(plist,n*sizeof(int));
int i=0;
for(i=0;i<n;++i){
*(plist+i)=i;
printf("%d ",*(plist+i));
}
}
- 一维动态数组的分配,可以使用
malloc
来完成; - 对于二位数组来说,
c
语言是使用一维数组的一维数组来模拟二位数组的;
- 假设声明的是一个
int x[3][5]
这样的一个数组,对于这样的数组进行保存,所以需要访问里面的元素首先需要确定行数x[0]
,然后在确定列数[0],[1],[2]
就可以访问里面的元素了,首先取得的地址表示的是x[i]
表示的是第i
行第0
个元素的地址,然后可以通过j*sizeof(int)
,就可以访问x[i][j]
;
通过一个malloc
来构建二位数组:
#include<stdio.h>
#include<stdlib.h>
#define MALLOC(p,s)\
if(!((p)=malloc(s))){\
fprintf(stderr,"Insufficient memory");\
exit(EXIT_FAILURE); \
}
int **make2Array(int rows, int cols)
{
int **x, i;
MALLOC(x, rows*sizeof(*x));
for (i = 0; i < rows; i++)
{
MALLOC(x[i], cols * sizeof(**x));
}
return x;
}
int main()
{
int rows = 10;
int cols = 10;
int **x = make2Array(rows, cols);
for (rows = 0; rows < 10; ++rows)
{
for (cols = 0; cols < 10; ++cols)
{
x[rows][cols]=cols;
}
}
for(rows=0;rows<10;++rows){
for(cols=0;cols<10;++cols){
printf("%d ",x[rows][cols]);
}
printf("\n");
}
}
- 归纳两个动态内存需要的函数
void *calloc(size_t nmemb, size_t size);
: 用于分配用户指定大小的一块存储区,并且将这块区域全部清0
,然后返回内存空间的地址;void *realloc(void *ptr, size_t size);
:是可以使用malloc
以及realloc
来实现的,realloc
函数的作用是调整当前所使用空间的大小为S
,并且需要保证原始空间的内容是不变的,如果S
是大于原始空间的,那么就新分配空间来使用,里面的内容是不确定的,如果S
是小于原始空间的那么多余的内容就会被释放;
#define REALLOC(p,s)\
//
if(!((p)=realloc(p,s))){\
fprintf(stderr,"Insufficient memory);
exit(EXIT_FAILURE);\
}
对于三位数组来数,也是通过一维数组的一维数组的一维数组进行模拟的;