C进阶:指针的进阶(1)

简介: C进阶:指针的进阶(1)

回归

哈喽哈喽大家好呀,我是灰灰快醒醒,时隔一个月又与大家见面了。众所周知,期末考试是中国教育部为大学生专门研发的一款开放式大逃杀游戏,学生需要扮演大难将至而绝望的人类,与小骚书共同完成《期末复习》的任务,不断逃离挂科的局面......所以作者一个月没写文章(借口)。

好了回归正题,今天讲解的内容是指针的进阶,我们继续探讨指针的高级主题(假装一本正经的样子)。

简要回顾(指针的简介)

我们都知道,计算机当中的内存会划分为一个个内存单元,每个单元都有独立的编号地址,而地址在C语言中称为指针。简:编号=地址=指针

指针(地址)需要存储起来——存储至变量中,该变量为指针变量。指针变量的大小根据(32/64)位平台分为(4/8)两种大小。

新内容学习

字符指针

顾名思义:字符指针就是指向字符的指针,所以其类型为char*。

一般使用如下:

#include<stdio.h>
 
int main()
{
  char ch = 'a';
    //定义指针变量p,指向ch的类型为字符类型
  char* pc = &ch;
  *pc = 'b';
  return 0;
}

还有一种使用方法如下:

#include<stdio.h>
 
int main()
{
    //这里是将一个字符串放入到pstr指针变量里面了吗?
  char* pstr = "hello";
  printf("%s\n", pstr);
  return 0;
}

这段代码的打印结果就是是“hello”,所以就会有人误解为将这一整段字符串放入指针pstr里面了,但实际上是将hello的首字符的地址放入了pstr指针当中

上面代码的意思就是把一个常量字符串的首字符h的地址存放到指针变量pstr当中了

下面再看这样一道题:

#include<stdio.h>
 
int main()
{
  char str1[] = "hello";
  char str2[] = "hello";
  char* str3 = "hello";
  char* str4 = "hello";
 
  if (str1 == str2)
    printf("str1 and str2 are same\n");
  else  
    printf("str1 and str2 are not same\n");
 
  if (str3 == str4)
    printf("str3 and str4 are same\n");
  else
    printf("str3 and str4 are not same\n");
    
  return 0;
}

上面一段代码的结果又是什么,让我们看一下输出:

为何会出现这样的结果,让我们来逐一分析一下:

要首先记住这几个关键的概念:

1.般情况下,数组名代表的是数组首元素的地址。

2.常量字符串是不允许被修改的。

(1)str1 和 str2 :分别创建了str1[ ]和str2[ ]这两个独立的数组,所以它们在内存中的存放的地址也肯定不相同,所以首个字符的地址也肯定不同,所以判断出来是不相同的。

(2)str3 和 str4 : 首先定义一个指向hello第一个字符的指针变量str3,然后因为上面第二个概念嘛,定义第二个指针变量str4一定还是指向同一个字符串的第一个字符,所以它们指向的是同一个位置。

指针数组

定义:指针数组是一个存放指针的数组,数组中的每一个元素的类型是指针类型

数组我们已经知道的有整型数组与字符数组等。

int arr[ ]

char arr[ ]

它们的类型一个是整型int,一个是字符类型char

因此类比得到整型指针数组和字符指针数组

int* arr[ ]

char* arr[ ]

数组指针可以用来模拟二维数组,举例如下:

#include<stdio.h>
 
int main()
{
  int arr1[] = { 1,2 };
  int arr2[] = { 3,4 };
    //定义一个指针数组,两个元素分别为前面两个数组的首元素地址
  int* arr[] = { arr1,arr2 };
  int i = 0;
    //循环遍历数组
  for (i = 0; i < 2; i++)
  {
    int j = 0;
    for (j = 0; j < 2; j++)
    {
        //*(*(arr + i) + j) -> *(arr[i] + j) -> arr[i][j]
      printf("%d ", *(*(arr + i) + j));
    }
    printf("\n");
  }
  return 0;
}

数组指针

定义:能够指向数组的指针。

基本书写格式:类型 (*数组指针名)[元素数量]

eg:int (*p) [10]

解释:p先和*结合,说明p是一个指针变量,然后指向的是一个数组大小为10的整型数组,所以p是一个指针,指向数组,叫做数组指针。

这里要注意: [ ]的优先级是大于*的,所以要先使用()以此保证p与*先结合。

那数组指针是怎么使用的呢?

既然数组指针指向的是数组,那数组指针中存放的应该是数组的地址。

一个数组指针的使用:还是以遍历二维数组为例:

#include <stdio.h>
 
//注意二维数组传参时,数组指针还是可以省略行,不可以省略列
void print_arr(int (*p)[5],int row, int col)
{
  int i = 0;
  for (i = 0; i < row; i++)
  {
    int j = 0;
    for (j = 0; j < col; j++)
    {
      printf("%-3d", p[i][j]);
    }
    printf("\n");
  }
}
 
int main()
{
  int arr[3][5] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
  //数组名arr,表示首元素的地址
  //但是在二维数组当中,首元素就是第一行
  //所以这里传递的arr就是第一行的地址,也就是一维数组的地址
  //所以我们可以使用一个数组指针来接收一行的地址
  print_arr(arr, 3, 5);
  return 0;
}

打印结果如下:

学了指针数组和数组指针让我们一起来看看下面代码的意思:

int arr[5];
//定义一个整型数组,数组中共有五个元素
int *parr1[10];
//定义一个指针数组,每个元素的类型为int*,共有十个元素
int (*parr2)[10];
//定义一个数组指针parr2,其指向一个大小为10的整型数组
int (*parr3[10])[5];
//可以将*parr3[10]看作*p所以总的来说它是一个数组指针,
//指向一个大小为5的整型数组,而*parr3[10]又可以看成一个指针数组
//因此可以将它看成一个10行5列,每个元素为int的二维数组

这一期就讲到这里,感谢各位观众老爷支持。

相关文章
|
6月前
|
C语言
指针进阶(C语言终)
指针进阶(C语言终)
|
6月前
|
机器学习/深度学习 搜索推荐 算法
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
【再识C进阶2(下)】详细介绍指针的进阶——利用冒泡排序算法模拟实现qsort函数,以及一下习题和指针笔试题
|
6月前
|
C语言
指针进阶(回调函数)(C语言)
指针进阶(回调函数)(C语言)
|
6月前
|
存储 C语言 C++
指针进阶(函数指针)(C语言)
指针进阶(函数指针)(C语言)
|
6月前
|
编译器 C语言
指针进阶(数组指针 )(C语言)
指针进阶(数组指针 )(C语言)
|
6月前
|
搜索推荐
指针进阶(2)
指针进阶(2)
56 4
|
6月前
指针进阶(3)
指针进阶(3)
49 1
|
6月前
|
C++
指针进阶(1)
指针进阶(1)
49 1
|
6月前
|
存储 安全 编译器
C++进阶之路:何为引用、内联函数、auto与指针空值nullptr关键字
C++进阶之路:何为引用、内联函数、auto与指针空值nullptr关键字
53 2
|
7月前
|
C语言
C语言进阶:进阶指针(下)
C语言进阶:进阶指针(下)
51 2