数组的简单总结
数组小结
一、一维数组
1、一维数组的创建、初始化
数组的创建:数组是一组相同元素的集合
数组的创建方式:
type_t arr_name[ ]
//type_t 数组的元素类型
//const_n 常量表达式,用来指定数组的大小
数组创建的实例
int arr1[10];
char arr2[5];
double arr3[10];
注:在创建数组时,[]中只能给出常量,不能使用变量(down机)。
数组的初始化:数组的初始化是指,在创建数组的同时给数组的内容附上一些合理的初始值(初始化)。
下面是一些代码: int arr1[10]={1,2,3}; //部分初始化
int arr2[4]={1,2,3,4};//完全初始化
int arr3[]={1,5,6,8,9};
char arr4[3]={'a',98,'c'};
char arr5[]={'a','b','c'};
char arr6[]="abcdef"; 此时[]中的值为7,在”abcdef“字符串后还有'\0'
在数组创建时,如果不想确定的给出数组的大小,就得对数组进行初始化。
数组中元素的个数根据初始化的内容确定。
以下代码要很好区分在内存中的空间分配
char arr1[]="abc";
char arr[2]={'a','b','c'};
char* p="abcdef";
2、一维数组的使用
代码如下:
#include<stdio.h>
int main()
{
int arr[10]={0};
int i=0;
for(i=0;i<10;i++)
{
arr[i]=i;
printf("%d ",arr[i]);
}
return 0;
}
总结:
1)、数组是使用下标来访问的,下标从 0开始。
2)、数组的大小可以通过计算得到。 int arr[10];
int sz=sizeof(arr)/sizeof(arr[0]);
3、一维数组在内存中的存储
代码:
#include<stdio.h>
int main()
{
int arr[10]={0};
int i=0;
for(i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
printf("arr[%d]=%p\n",i,&arr[i]);
return 0;
}
输出的结果:
由输出的结果我们可以得到,随着下标的增长,元素的地址也在有规律的递增。
结论:数组在内存中是连续存放的
4、指针的初步介绍
为了很好的管理内存,我们对内存进行了详细的编址。
结论:
1)、内存中的一个内存单元(字节)对应一个地址。
2)、在32位的平台上一个指针的大小是4个字节,64位平台上是8个字节。
指针可以理解为一个变量,是一个专门用来存放地址的变量,通常我们讲的指针其实是一个变量。
指针变量的定义
int *ptr=NULL;//定义一个整形指针变量,初始化为NULL
char *ptr =NULL;//定义一个字符型指针变量,初始化为NULL
double*ptr=NULL;//定义一个双精度浮点数的指针变量,初始化为NULL
在得到指针以后,如果需要指针所指向的变量,则可以使用*
(解引用操作符)。 int n=10;
int *p_n=&n;//将num的地址放到p_n指针变量中
*p_n=20;//改变变量n的值
5、一维数组的指针访问
首先:
#include<stdio.h>
int main()
{
int arr[]={1,2,3,4,5,6,7,8,9,0};
printf("%p\n",arr);
printf("%d\n",*arr);
return 0;
}
输出结果:
由此可见:数组的数组名就是数组首元素的地址。
由首地址得到每个元素的地址:
#include<stdio.h>
int main()
{
int arr[10]={0};
int i;
for(i=0;i<sizeof(arr)/sizeof(arr[0]);++i)
{
printf ("&arr[%d]=%p\n",i,&arr[i]);
printf("%p\n",arr+i);
}
return 0;
}
输出结果:
由此:通过对数组名+整数的运算方式,可以得到数组每个元素的地址。
二、二维数组
1、二维数组的创建和初始化
二维数组的创建:
int arr[3][4];
char arr[3][5];
double arr[2][3];
二维数组初始化
int arr[3][5]={1,2,3,4};
int arr[3][4]={{1,2},{4,5}};
int arr[][4]={{2,3},{4,5}};
2、二维数组的使用
二维数组的使用也是通过下标的方式
#include<stdio.h>
int main()
{
int arr[3][4]={0};
int i=0;
for(i=0;i<3;i++)
{
int j=0;
for(j=0;j<4;j++)
{
arr[i][j]=i*4+j;
}
}
for(i=0;i<3;i++)
{
int j=0;
for(j=0;j<4;j++)
printf("%d",arr[i][j]);
}
return 0;
}
3、二维数组在内存中的存储
#include<stdio.h>
int main()
{
int arr[3][4]={0};
int i=0;
for(i=0;i<3;i++)
{
int j=0;
for(j=0;j<4;j++)
{
printf("&arr[%d][%d]=%p\n",i,j,&arr[i][j]);
}
}
return 0;
}
输出结果如下:
由此可知:二维数组在内存中也是来连续存储的
4、二维数组的指针访问
使用指针访问二维数组
代码:
#include<stdio.h>
int main()
{
int arr[3][4]={0};
int *p=&arr[0][0];
int i=0;
for(i=0;i<3*4;i++)
{
*(p+i)=i;
}
for(i=0;i<3;i++)
{
int j=0;
for(j=0;j<4;j++)
{
printf("%d",arr[i][j]);
}
}
return 0;
}
三、有关数组的运算
#include<stdio.h>
int main()
{
int a[]={1,2,3,4};
printf("%d\n",sizeof(a));
printf("%d\n",sizeof(a+0));
printf("%d\n",sizeof(*a));
printf("%d\n",sizeof(a+1));
printf("%d\n",sizeof(a[1]));
printf("%d\n",sizeof(&a));
printf("%d\n",sizeof(*&a));
printf("%d\n",sizeof(&a+1));
printf("%d\n",sizeof(&a[0]));
printf("%d\n\n\n\n",sizeof(&a[0]+1));
printf("%p\n",sizeof(a));
printf("%p\n",sizeof(a+0));
printf("%p\n",sizeof(*a));
printf("%p\n",sizeof(a+1));
printf("%p\n",sizeof(a[1]));
printf("%p\n",sizeof(&a));
printf("%p\n",sizeof(*&a));
printf("%p\n",sizeof(&a+1));
printf("%p\n",sizeof(&a[0]));
printf("%p\n",sizeof(&a[0]+1));
return 0;
}
输出结果:
#include<stdio.h>
#include<string.h>
int main()
{
char *p="abcdef";
printf("%d\n",sizeof(p));
printf("%d\n",sizeof(p+1));
printf("%d\n",sizeof(*p));
printf("%d\n",sizeof(p[0]));
printf("%d\n",sizeof(&p));
printf("%d\n",sizeof(&p+1));
printf("%d\n\n\n",sizeof(&p[0]+1));
printf("%d\n",strlen(p));
printf("%d\n",strlen(p+1));
printf("%d\n",strlen(*p)); //err
printf("%d\n",strlen(p[0])); //err
printf("%d\n",strlen(&p)); //x
printf("%d\n",strlen(&p+1)); //x
printf("%d\n",strlen(&p[0]+1));
return 0;
}
输出结果:
总结:
数组名代表数组的时候只有两种情况:
1、sizeof(数组名)
,这里的数组名代表整个数组,sizeof(数组名)
计算的是整个数组的大小
2、&数组名,这里的数组名代表整个数组,&数组名 取出的是数组的地址
除此之外,所有的数组名都表示数组首元素的地址
四、数组作为函数参数
当数组作为函数参数时,不会将整个数组传递过去,而只是把数组的首元素的地址传递过去,所以即使在函数参数部分写成数组的形式:int arr[]
,它表示的依然是一个指针:int* arr.
上一篇: 【总结】后缀数组
下一篇: leetcode最长回文子串