(一)数组名的理解
&arr[0];
arr;
通过之前的学习,我们可以知道,上面两行代码的意义相同,都是表示数组首元素的地址,但并不是所有情况都是这样,有两个例外
1.sizeof,sizeof中单独数组名,这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节
2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址
(二)使用指针访问数组
int main()
{
int arr[10] = { 0 };
int sz = sizeof(arr) / sizeof(arr[0]);
int* p = arr;
for (int i = 0; i < sz; i++)
{
scanf("%d", p + i);
}
for (int i = 0; i < sz; i++)
{
printf("%d ", *(p + i));
}
return 0;
}
这里的arr是数组首元素的地址,可以赋值给p,那么其实在这里arr和p是等价的,我们可以使用arr[i]访问数组,那么也可以用p[i]访问数组
int main()
{
int arr[10] = { 0 };
int sz = sizeof(arr) / sizeof(arr[0]);
int* p = arr;
for (int i = 0; i < sz; i++)
{
scanf("%d", p + i);
}
for (int i = 0; i < sz; i++)
{
printf("%d ", p[i]);
}
return 0;
}
(三)一维数组传参的本质
void test(int arr[])
{
int sz2 = sizeof(arr) / sizeof(arr[0]);
printf("sz2=%d", sz2);
}
int main()
{
int arr[10] = { 0 };
int sz1 = sizeof(arr) / sizeof(arr[0]);
printf("sz1=%d\n", sz1);
test(arr);
return 0;
}
观察上方代码和运行结果,发现数组传递给函数后,函数内部没有正确获得数组的元素个数,我们知道数组名是数组首元素的地址,所以本质上数组传递的是数组首元素的地址。所以函数形参部分理论上应该使用指针变量来接受首元素的地址,但是正因为函数参数部分是本质指针,所以在函数内部是没办法求数组元素个数的
(四)冒泡排序 冒泡排序的核心思想就是:两个相邻的元素进行比较
1.理论基础
冒泡排序的核心思想就是:两个相邻的元素进行比较,我们给一个整型数组,里面存放10个乱序的整型元素,要求将它们从小到大排序,我们首先两两做比较,将第一个与第二个相比,如果第一个元素大于第二个元素,那么将它们交换顺序,否则不变,依次类推,那么想要完成全部排序,我们需要进行9趟冒泡排序,完成一趟冒泡排序之后,最大的数已经排到最后面,而下一趟只需比较前9位数,所以在第一次冒泡排序里面我们需要交换9次,而下一趟去除最后一位数不用排,只需交换8次,依次类推
2.代码实现
void dubble_test(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
int j = 0;
{
for (j = 0; j < sz - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
int temp = arr[j+1];
arr[j + 1] = arr[j];
arr[j] = temp;
}
}
}
}
}
void print(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[10] = { 1,2,4,9,3,6,7,4,23,5 };
int sz = sizeof(arr) / sizeof(arr[0]);
print(arr, sz);
dubble_test(arr, sz);
print(arr, sz);
return 0;
}
3.代码优化 上述代码中需要将数组里的元素全部交换一遍,但是如果数组中元素已经有序,那么就不需要依次排序交换了,如下代码
void dubble_test(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
int flag = 0;//假设这一趟已经有序
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
int temp = arr[j+1];//发生交换就说明无序
arr[j + 1] = arr[j];
arr[j] = temp;
flag = 1;
}
}
if (flag ==0)//这一趟没有交换就说明已经有序,后续无需交换
{
break;
}
}
}
void print(int arr[], int sz)
{
int i = 0;
for (i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
printf("\n");
}
int main()
{
int arr[10] = { 1,2,4,9,3,6,7,4,23,5 };
int sz = sizeof(arr) / sizeof(arr[0]);
print(arr, sz);
dubble_test(arr, sz);
print(arr, sz);
return 0;
}
(五)二级指针
指针变量也是变量,所以也有地址,那么用什么去存储指针变量的地址呢?答案就是二级指针
int main()
{
int n = 0;
int* p1 = &n;//一级指针
int** p2 = &p1;//二级指针
return 0;
}
我们知道可以通过解引用操作符*来获取指针指向的内容,那么二级指针是否也可以用*来获取最初变量的值呢,如下代码实现
int main()
{
int n = 10;
int* p1 = &n;//一级指针
int** p2 = &p1;//二级指针
printf("%d", **p2);//*p2=p1,**p2=*p1=n
return 0;
}
(六)指针数组
我们知道,整型数组,就是存放整型的数组,字符数组,就是存放字符的数组,而指针数组呢,没错,就是存放指针的数组
1.指针数组模拟二维数组
我们可以通过int*parr里面的下标依次找到arr1,arr2,arr3,再通过arr里面里面的下标找到其中的元素,这就相当于二维数组

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[3] = {arr1,arr2,arr3};
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%d ", parr[i][j]);
}
printf("\n");
}
return 0;
}





1421

被折叠的 条评论
为什么被折叠?



