嗨~友友们好,我是林林。
接下来是指针(2),不要走开,精彩马上就来~
目录
一、数组名
数组名就是数组首元素(第⼀个元素)的地址。但有两个例外:
(1)sizeof(数组名),sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的大小, 单位是字节;
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n", sizeof(arr));//注意:结果为40
return 0;
}
(2)&数组名,这里的数组名表示整个数组,取出的是整个数组的地址(整个数组的地址和数组首元素的地址是有区别的)。
二、arr和&arr的区别
(1)arr表示数组第一个元素的地址,arr+1跳过4个字节(这里以int类型为例);
(2)&arr表示整个数组的地址,&arr+1跳过(4*sz)个字节;(仍以int为例,sz是指数组的长度)。
sz= sizeof(arr) / sizeof(arr[0]);
三、指针访问数组
#include <stdio.h>
int main()
{
int arr[10] = {0};
sz = sizeof(arr) / sizeof(arr[0]);
int* p = arr;//首元素的地址
//输入
for(int i = 0 ; i < sz ; i ++)
{
scanf("%d",p + i);//p+i表示的是地址
//scanf("%d",arr + i);//arr地址存入了p中,arr==p
}
//输出
for(int j = 0 ; j < sz; j ++)
{
printf("%d ",*(p + j));//*(p+j)表示的是数组元素
//printf("%d ",arr[j]);//之前学到的用下标访问数组
//printf("%d ",p[j]);//p == arr
}
return 0;
}
因此:p+i == arr+i; *(p+j) == arr[j] == p[j] (这里很重要!!)
四、一维数组传参
(1)本质上数组传参传递的是数组首元素的地址。因此不能将arr传入数组再计算元素个数。(在函数内部我们写 sizeof(arr) 计算的是⼀个地址的大小(单位字节)而不是数组的大小(单位字节)。正是因为函数的参数部分是本质是指针,所以在函数内部是没办法求的数组元素个数的。)
(2)⼀维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。
void test(int arr[])//参数写成数组形式,本质上还是指针
{
printf("%d\n", sizeof(arr));
}
void test(int* arr)//参数写成指针形式
{
printf("%d\n", sizeof(arr));//计算⼀个指针变量的⼤⼩
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
test(arr);
return 0;
}
五、冒泡排序
两两相邻元素进行比较
void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{
int i = 0;
for(i=0; i<sz-1; i++)//假设有sz个数,只需要比较sz-1次
{
int j = 0;
for(j=0; j<sz-i-1; j++)
{
if(arr[j] > arr[j+1])
{
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp; //交换位置
}
}
}
}
int main()
{
int arr[] = {3,1,7,5,8,9,0,2,4,6};
int sz = sizeof(arr)/sizeof(arr[0]);
bubble_sort(arr, sz);
//依次打印元素
int i = 0;
for(i=0; i<sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
这样减少了不必要的比较:
void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{
int i = 0;
for(i=0; i<sz-1; i++)
{
int flag = 1;//假设这⼀趟已经有序了
int j = 0;
for(j=0; j<sz-i-1; j++)
{
if(arr[j] > arr[j+1])
{
flag = 0;//发⽣交换就说明,无序
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
if(flag == 1)//这⼀趟没交换就说明已经有序,后续不用排序了
break;
}
}
int main()
{
int arr[] = {3,1,7,5,8,9,0,2,4,6};
int sz = sizeof(arr)/sizeof(arr[0]);
bubble_sort(arr, sz);
int i = 0;
for(i=0; i<sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
六、二级指针
#include <stdio.h>
int main()
{
int a = 0 ;
int * p = &a;
int * *pp = &p;
return 0;
}
**pp:*pp 代表指向的是p(指针变量)的地址;**pp 是对二级指针解引用。
一级指针的类型为:int * ;二级指针类型为int **。(这里只是举一个例子,也可能是char* 、char**)
七、指针数组
指针数组就是存放指针(地址)的数组,本质上是数组。指针数组的每个元素是地址,⼜可以指向⼀块区域。
八、指针数组模拟二维数组
#include <stdio.h>
int main()
{
int arr1[] = {1,2,3,4,5};
int arr2[] = {2,3,4,5,6};
int arr3[] = {3,4,5,6,7};
//数组名是数组⾸元素的地址,类型是int*的,就可以存放在parr数组中
int* parr[3] = {arr1, arr2, arr3};
int i = 0;
int j = 0;
for(i=0; i<3; i++) //共3个数组
{
for(j=0; j<5; j++) //每个数组有5个元素
{
printf("%d ", parr[i][j]);
}
printf("\n");
}
return 0;
}
这里解释一下parr[i][j] :根据前面的总结 parr[i] == *(parr+i) (得到每一个整形数组) ,parr[i][j] == (*(parr+i))[j] (每个整形数组的元素)。
上述的代码模拟出⼆维数组的效果,实际上并⾮完全是⼆维数组,因为每一行并非是连续的。
九、写在最后
友友们~指针开头难,一定要多看多学多总结,相信我们一定可以学会的,加油!!
我是林林,拜拜~