【进阶指针一】字符数组&数组指针&指针数组(上)

简介: 【进阶指针一】字符数组&数组指针&指针数组

1.初阶指针内容回顾


1.内存被划分为小的内存单元,每个内存单元都有一个编号,这个内存编号就是所谓的地址,也被叫做指针(内存编号=地址=指针)。


2.指针变量是一个变量,存放的是地址,地址能够唯一标识一块内存单元。


3.指针变量大小是固定的4/8个字节(32/64位平台上)。


4.指针变量类型决定了(1)指针在+-整数时的跳过多少个字节;(2)指针在解引用的时候访问的权限。


2.字符指针

2-1 字符指针长什么样?

int main()
{
    //代码一:
  char ch = 'a';
  char* p1 = &ch;
  printf("字符'a'的地址:>%p\n", p1);
  printf("对指针解引用得到的是指针指向的那个目标:>%c\n", *p1);
  printf("\n\n\n");
    //代码二:
  char* p2 = "hello world";
  printf("字符'h'的地址:>%p\n", p2);
  printf("对指针解引用得到的是指针指向的那个目标:>%c\n", *p2);
  printf("%s\n", p2);
  return 0;
}


a70e18a63f664f3cba822da703e9a079.png

2-2 误区:


误以为代码2中p2指针变量是存放着字符串,实际上p2所指向的是字符串"abcdef”中首个字符'a'的地址(原因有两点:1.指针变量在x86位(32位机器下)是4个字节,但是"abcdef“有7个字符,一个指针只能存放一个地址;2.通过指针解引用打印出'a'),同时因为字符串"abcdef"在内存(字符常量区)中的空间是连续的,所以只要拿到字符串首个元素'a'的地址就可以访问到整个字符串的内容。


2-3  代码一和代码二的异同:


1. 同:


(1)指针类型:p1和p2都是字符指针变量,都是存放的是字符a的地址。


(2)打印字符'a:打印出'a'都是通过拿到字符指针变量内存放的地址进行解引用,得到的都是指针变量所指向的那个变量。


2. 异


(1)字符'a'的存储位置:代码1中的'a'存放在栈区,代码2中的'a'存放在字符常量区(通过下方截图可以证明)


f2aa645d44b14b8a819dce269baf2604.png


2-4 关于字符常量区:


8af7a3bd1d434ec4900fcdd26101ebda.png

对于上图的解释3:


- 既然位于字符常量区的"abcdef"是不允许修改的


那么在p2指向这块内存空间的时候就会产生隐患,一旦通过解引用试图修改就会造成程序的运行时错误,程序瘫痪;


- 因此使用const修饰(也就是const char* p2="abcdef")来阻止对指针解引用试图修改的行为 ,及时给出编译时错误,程序压根编译不通过。


2-5 一道为了区分栈区和字符常量区&&字符数组和字符指针的面试题:


int main()
{
  const char* ptr1 = "abcdef";
  const char* ptr2 = "abcdef";
  char arr1[] = "abcdef";
  char arr2[] = "abcdef";
  if (ptr1 == ptr2)
  {
    printf("ptr1==ptr2\n");//bingo
  }
  else
  {
    printf("ptr1!=ptr2\n");//error
  }
  if (arr1 == arr2)
  {
    printf("arr1==arr2\n");//error
  }
  else
  {
    printf("arr1!=arr2\n");//bingo
  }
  return 0;
}

237514c5562d4271b0623bfd1a7d2348.png

23b8cbf0cba94265a26d70267b98876b.png

3.指针数组

其实下面要讲的指针数组和数组指针都是一种类型(类似整型,double,float)

3-1 指针数组长什么样捏?

//整型数组
int arr1[5]={1,2,3,4,5};//存放整型的数组
//字符数组
char arr2[5]={'a','b','c,''d','\0'};//存放字符的数组
//指针数组:指针是修饰,数组是名词,主角
int* arr3[5]={&arr1[0],&arr1[1],&arr1[2] ,&arr1[3] ,&arr1[4]};//存放指针的数组
//指针数组的意义:看着食之无味,弃之可惜
//实际上作用大着捏,我们指针数组的意义和普通数组的意义类似,
//都是对方便对相同类型元素(在这里的类型元素是指针)统一处理:比如修改和打印


3-2 初级使用(或者说给你看一下基本使用):

int main()
{
  //简单用法:
  int a = 10;
  int b = 20;
  int c = 30;
  //没有数组指针的情况
  int* p1 = &a;
  int* p2 = &b;
  int* p3 = &c;
  //有数组指针的情况
  int* arr[3] = { &a,&b,&c };
  for (int i = 0; i < 3; i++)
  {
    printf("%d\n", *(arr[i]));
  }
  return 0;
}

8944d4eda67c43a596462ea58655a47c.png


cf7fa4e436024a2694bfca5dd02c62e1.png

3-3这才是指针数组的正确使用方法!【指针数组模拟打印二维数组】

这和arr[3][5]的区别在于arr[3][5]在内存中中每一个元素的地址都是连续的,而指针数组模拟的二维数组这种方式的地址不是连续的。

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* arr[3] = { arr1,arr2,arr3 };
  for (int i = 0; i < 3; i++)
  {
    for (int j = 0; j < 5; j++)
    {
            //printf("%d\t",arr[i][j]);//way1
            //printf("%d\t", *(arr[i] + j));//way2
              printf("%d\t",*(*(arr+i)+j);//way3
            //实际上way1和way2在编译器翻译过程中会自动转换为way3
    }
    printf("\n");
  }
  return 0;
}

a4802821b8c644658c5ff485fab53f21.png

c56f530348aa4c00a152f141a6f0e5cd.png


目录
相关文章
|
1月前
使用指针访问数组元素
【10月更文挑战第30天】使用指针访问数组元素。
36 3
|
19天前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
23天前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
23天前
|
容器
在使用指针数组进行动态内存分配时,如何避免内存泄漏
在使用指针数组进行动态内存分配时,避免内存泄漏的关键在于确保每个分配的内存块都能被正确释放。具体做法包括:1. 分配后立即检查是否成功;2. 使用完成后及时释放内存;3. 避免重复释放同一内存地址;4. 尽量使用智能指针或容器类管理内存。
|
23天前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。
|
26天前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
48 4
|
1月前
使用指针访问数组元素
【10月更文挑战第31天】使用指针访问数组元素。
43 2
|
1月前
|
算法 索引
单链表题+数组题(快慢指针和左右指针)
单链表题+数组题(快慢指针和左右指针)
39 1
|
2月前
|
存储
如何使用指针数组来实现动态二维数组
指针数组可以用来实现动态二维数组。首先,定义一个指向指针的指针变量,并使用 `malloc` 为它分配内存,然后为每个子数组分配内存。通过这种方式,可以灵活地创建和管理不同大小的二维数组。
|
2月前
|
存储
如何通过指针数组来实现二维数组?
介绍了二维数组和指针数组的概念及其区别,详细讲解了如何使用指针数组模拟二维数组,包括定义与分配内存、访问和赋值元素、以及正确释放内存的步骤,适用于需要动态处理二维数据的场景。