深入理解指针(2)

发布于:2024-05-20 ⋅ 阅读:(94) ⋅ 点赞:(0)

1.数值名的理解

数组名属于地址,而且是数组首元素的地址

# include <stdio.h>
int main ()
{
  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);
  return 0 ;
}

输出的结果:

 

由上图可知数组名就是数组首元素的地址 

以下有特殊的两种情况:
 

sizeof(数组名),sizeof中单独放数组名,这⾥的数组名表⽰整个数组,计算的是整个数组的⼤⼩,单位是字节
&数组名,这⾥的数组名表⽰整个数组,取出的是整个数组的地址(整个数组的地址和数组⾸元素的地址是有区别的)

2.使用指针访问数组

如下代码:
 

# include <stdio.h>
int main ()
{
 int arr[ 10 ] = { 0 };
 // 输⼊
 int i = 0 ;
 int sz = sizeof (arr)/ sizeof (arr[ 0 ]);
 // 输⼊
 int * p = arr;
 for (i= 0 ; i<sz; i++)
{
 scanf ( "%d" , p+i);
 //scanf("%d", arr+i);// 也可以这样写
}
 // 输出
 for (i= 0 ; i<sz; i++)
{
 printf ( "%d " , p[i]);
}
 return 0 ;
}

其中*(p+i) = p[i];

       arr[i]  = *(arr+i);

3.一维数组传参的本质 

    数组传参的时候本质上传递的是数组首元素的地址

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 ;
}

总结⼀维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。

4.冒泡排序

冒泡排序的核⼼思想就是:两两相邻的元素进⾏⽐较
如下代码就是冒泡排序:
 
// ⽅法 1
void bubble_sort ( int arr[], int sz) // 参数接收数组元素个数
{
 int i = 0 ;
for (i= 0 ; i<sz -1 ; i++)
{
 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);
for (i= 0 ; i<sz; i++)
{
printf ( "%d " , arr[i]);
}
return 0 ;
}
// ⽅法 2 - 优化
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);
 for (i= 0 ; i<sz; i++)
{
printf ( "%d " , arr[i]);
}
return 0 ;
}
 

5.二级指针 

指针变量作为变量,其变量的地址便储存在二级指针内

 

 对于⼆级指针的运算有:

*ppa 通过对ppa中的地址进⾏解引⽤,这样找到的是 pa *ppa 其实访问的就是 pa .
int b = 20 ;
*ppa = &b;  //等价于pa = &b

 **ppa 先通过 *ppa 找到 pa ,然后对 pa 进⾏解引⽤操作: *pa ,那找到的是 a .

 

**ppa = 30 ;
// 等价于 *pa = 30;
// 等价于 a = 30;

 

6.指针数组

指针数值是存放指针的数组,指针数组的每一个元素都是用来存放地址(指针)的。

如下图:


 

 指针数组的每一个元素是地址,又可以指向一块区域。

7.指针数组模拟二维数组

 如下面代码所示:

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

可以通过下图更好的理解该代码:
 

上述的代码模拟出⼆维数组的效果,实际上并⾮完全是⼆维数组,因为每⼀⾏并⾮是连续的。

网站公告

今日签到

点亮在社区的每一天
去签到