目录
一维数组
一、存储
在计算机存储数据时,只记开头第一个字节的地址,一个字节8bit
- 为什么指针可以指向数组?(结构体指针可以指向结构体数组也是这样)
因为数组的地址和第一个数的地址一
二、传参
1.借助指针
如果想把一个数组作为参数传入函数中,可以借助指针,具体如下 :
void m1(int*m)//参数是指针类型
{printf("%d\n",m);}
int main(arc(),char *argv[])
{int arr[]={1,2,3,4,5,6,7,8,9};
int w=100;
int *m1=&w;//指向一个整数
int *m2=arr;//指向一个数组
m1(&w);//传参传w的地址
m1(arr);//传参传数组首地址
2.直接传数组
特别注意:在写函数传参时,通过传递数组名参数,试图在函数内部求数组长度是不可以的。
int fuction(int[]arr)
{
int le;
le=sizeof(arr)/sizeof(arr[0]);//不可以
return le;
}
因此:写函数时传参如果是指针类型且指向的是数组,要传入另外一个代表数组长度的数。如果传参仅仅是指针类型则代表传参是指针类型所指向的是一个数。
三、使用malloc申请一维数组
int*k=(int*)malloc(60);//申请60个字节的空间并按照int类型的数组进行切分
//int型是占4个字节,所以上面申请的是长度15的数组
k[20]=99;
printf("%d\n",k[20]);//越界操作,高级语言不允许这么操作,例如java会自动拦截,c和c++可能出现
1.溢出攻击
越界操作造成本程序占用其它程序的内存,这时其它程序戛然而止
2.数组与sizeof相关使用
int arr={1,2,3,4}//16
int*k=(int*)malloc(60);//指针类型
int m1=sizeof(k)//8,不能用sizeof输出指针所指向的大小,输出的是指针的大小
int m2=sizeof(*k)//4 此时输出的是指针所指向第一个数字的大小
int m3=sizeof(arr)//输出arr的内存大小4*4=16
如果想通过sizeof来获取数组长度,应该这样写:
sizeof(arr)/sizeof(arr[0]);
多维数组
1、基本类型多维数组
#include<stdio.h>
#include<stdlib.h>
int main(int argc,char*argv[])
{int arr1[]={1,1,2,3};//层层递进,对应那个数由内到外代表层数
int arr2[3][4]={{1,1,3,5},{3,3,5,8},{2,2,8,9}};
int arr3[2][2][5]={
{
{1,1,1,3,7},{5,5,7,8,9}
},
{
{3,3,3,3,6},{1,1,1,6,9}
}
};
return 0;
}
2、结构体类型多维数组
注意:定义数组赋值时是拷贝,数组内的数据改变不会对原来的数据产生影响。
#include<stdio.h>
#include<stdlib.h>
typedef struct AA{
int x1;
int x2;
}A,B;
int main(int argc,char *argv[])
{
A k1,k2,k3,k4,k5,k6,k7,k8,k9;
int n1,n2,n3,n4,n5;
A arr[]={k1,k2,k3};
A arr2[[2][3]]={{k1,k2,k3},{k4,k5,k6}};
//这里arr2[1][2]=k6,相当于拷贝了k6过去,如果修改了k6.x1不影响arr2[1][2].x1的值
//************此处和java不一样,java相当于就是同一份
k6.x1=66;//通过结构体
arr2[1][2]=66;//通过结构体数组索引
return 0;
}
arr[2][3]内存图示:
函数传参:结构体是拷贝了一份,数组是指同一个。(与数组赋值然后修改值区别开来)
#include<stdio.h>
#include<stdlib.h>
typedef struct AA{
int x1;
int x2;
}A,B;
void m1(A k)
{
k.x1=11;
}
void m2(int k[])
{
k[0]=100;
}
int main(int argc,char *argv[])
{ A k;
int s1={1,2,3};
m1(k);//传参结构体拷贝,修改不影响数值
m2(s1);//数组是同一个,修改影响数值
}
3、使用malloc申请多维数组
int s1[]={1,2,3};
int *f1=(int*)malloc(40);//int*f1相当于一个一维数组,申请40个bit的空间按照int划分
//int*f1=(int*)malloc(sizeof(int)*10)等同上行
int**f2=(int**)malloc(sizeof(int*)*5);//二维数组:相当于申请了一个存放地址的指针数组,每个指针指向不同的数组
f2[0]=f1;
f2[1]=(int*)malloc(8);
f2[2]=s1;
int***f3=(int***)malloc(sizeof(int**)*2);//三维数组,指针的※数量代表了数组的维度。
5.指针数组:可以存放该类型的指针或者该类型的数组
例子:当声明A**arr:可以直接存放结构体指针,也可以存放一维结构体数组,也可以两者混存。
A**arr3=(A**)malloc(sizeof(A*)*10);
//申请十个结构体指针类型的空间,形成一个数组
A x;
A*K1=&x;
arr3[0]=k1;
arr3[0]->a=20;
再如以下指针数组可存放,int*和int的数组
int *s=&s1;
int box[]={0,1,2};
int**arr=(int**)malloc(sizeof(int*)*10);
arr[0]=s;
arr[0]=box;
6.注意(以下是由于语言演变引发的不规范性)
- 对于基本数据类型:
int*f1=(int*)malloc(sizeof(int)*10);//申请空间存放整形,但是可以存放整形的指针;
int**bxx=(int**)malloc(sizeof(int*)*5);//申请空间存放指针,但是仍然可以存放整形int数;
以上两个例子:(基本数据类型指针的特殊性)
虽然malloc申请的是指针/基本数据类型空间仍然可以存放基本数据类型/指针
- 对于结构体类型
A*arr=(A*)malloc(sizeof(A)*10);//申请的空间是按照结构体,不能存放结构体指针
A**arr=(A**)malloc(sizeof(A*)*10);申请的是结构体指针空间,不能存放结构体