目录:
(1)数组名的理解
(2)使用指针访问数组
(3)一维数组传参的本质
(4)冒泡排序
(5)二级指针
(6)指针数组
(7)指针数组模拟二维数组
1.数组名的理解
数组名是数组首元素的地址;
下面做一个小测试:
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
printf("&arr[0] = %p\n",&arr[0]);
printf("arr = %p\n",arr);
但是有两个例外:
(1)sizeof(数组名) 这里的数组名表示整个数组,计算的是整个数组大小
(2)&数组名 这里的数组名也是整个数组,取出的是整个数组的地址:数组的地址+1 要跳过一个数组
其他的所有数组名都是数组首元素的地址
2 使用指针访问数组
int arr[10] = {0};
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
//使用下标的方式访问数组
for(i = 0;i < sz;i++)
{
scanf("%d",&arr[i]);
}
for(i = 0;i < sz;i++)
{
printf("%d\n",arr[i]);
}
//使用指针来访问数组
int arr[10] = {0};
int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
int* p = &arr[0];//也可以直接 = arr
for(i = 0;i < sz;i++)
{
scanf("%d",p + i);//p+i是下表为i元素的地址//这里的p也可以直接携程arr
}
for(i = 0;i < sz;i++)
{
printf("%d\n",*(p + i));//解引用下标为i的元素的地址 //*(arr + i)完全等价于arr[i]
}
注意:加法符合交换律 --->*(arr + i) 等价于 *(i + arr)
另外 arr[i] 也等价于 i[arr]; //[]只是一个操作符
1、数组就是数组,是一块连续的空间,是一个可以存放一个或者多个数组的
2、指针变量是一个变量,是可以存放地址的变量
数组和指针不是一回事,但是可以是一种指针来访问数组
为什么可以使用指针来访问数组呢?
(1)数组在内存中是连续存放的
(2)指针的运算可以很方便地遍历数组,取出数组内容
3.一维数组传参的本质
void test(int arr[10])//传来的是首元素的地址int* arr
//所以写成arr[]也行
{
int sz2 = sizeof(arr) / sizeof(arr[0]);
printf("sz2 = %d\n",sz2);//打印sz2 = 1
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int sz1 = sizeof(arr) / sizeof(arr[0]);
printf("sz1 = %d\n",sz1);//sz1 = 10;
test(arr);//arr是数组名,数组名表示数组首元素的地址,传过去的是首元素的地址
//数组传参的本质:传递的是数组首元素的地址
//所以形参即使写成数组的形式,本质上也是一个指针变量
return 0;
}
数组传参的时候,形参可以写成数组,也可以写成指针
写成数组的形式,最简单,是为了方便理解,容易接受这种语法
但是即使写成数组的形式,本质上还是指针
void test(int* arr,int sz)//
{
int i = 0;
for(i = 0;i < sz;i++)
{
printf("%d ",arr[i]);
//printf("%d ",*(arr + i));;两种写法均可以
}
}
4.冒泡排序
先搞清楚冒泡排序是怎么样的:两两相邻的元素比较,不满足顺序就交换,满足顺序就找下一对
void input(int* arr,int sz)
{
int i = 0;
for(i = 0;i < sz;i++)
{
scanf("%d",arr+i);
}
}
void bubble_sort(int* arr,int sz)
{
int i = 0;
for(j = 0;j < sz - 1 - i;j++)
{
if(arr[j] < arr[j+1])
{
flag = 0;
//交换
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
void print_arr(int* arr,int sz)
{
int i = 0;
for(i = 0;i < sz;i++)
{
printf("%d ",arr[i]);
}
}
int main()
{
int arr[10] = {0};
//输入一些值
int sz = sizeof(arr) / sizeof(arr[0]);
input(arr,sz);
//排升序(冒泡排序)
bubble_sort(arr,sz);
print_arr(arr,sz);
return 0;
}
但是存在情况:10 9 7 8 6 5 4 3 2 1,这种情况用上面的代码处理起来就非常浪费时间;
于是我们可以对上述代码稍作修改:增加哨兵值
void bubble_sort(int* arr,int sz)
{
int i = 0;
for(i = 0;i < sz;i++)
{
int flag = 1;//哨兵值
int j = 0;
for(j = 0;j < sz - 1 - i;j++)
{
flag = 0;
//交换
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
if(flag)
break;
}
}
5.二级指针
(前面讲的都是一级指针)
什么是二级指针?
int a = 10;
int* pa = &a;//pa是一级指针变量
int** ppa = &pa;//ppa就是二级指针变量
地址 指向的值 指向的变量
0x0012ff40 10 a (int)
0x003f4800 0x0012ff40 pa(int*)
0x004ff460 0x003f4800 ppa(int**)
二级指针变量是用来存放一级指针变量的地址
解引用:**ppa 就是a
*ppa 就是pa
注意:二级指针和二维数组没有对应关系
可以有多级指针,一般不会超过三级指针
6.指针数组
指针数组
到底是指针还是数组???
char arr[10];//字符数组——存放字符的数组
int arr[5];//整型数组——存放整型的数组
那么,指针数组——存放指针的数组,数组的每个元素都是指针类型
指针数组的每个元素都是地址(指针),又可以指向同一块区域
char* arr[5];//存放字符指针的数组
int* arr[6];//存放整型指针的数组
int main()
{
int a = 10;
int b = 20;
int c = 30;
int* arr[3] = {&a,&b,&c};
int i = 0;
for(i = 0;i > 3;i++)
{
printf("%d ",*(arr[i]));
}
return 0;
}
7.指针数组模拟二维数组
#include<stdio.h>
int main()
{
int arr1[5] = {1,2,3,4,5};
int arr2[5] = {2,3,4,5,6};
int arr3[5] = {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++)
{
for(j = 0;j < 5;j++)
{
printf("%d ",parr[i][j]);//*(*(parr + i) + j)
}
printf("\n");
}
return 0;
}
运行结果如图: