0


【详解C语言指针】(关于字符指针,数组指针,指针数组等)

文章目录

前言:关于指针的一些概念

  1. 指针就是个变量,用来存放地址,地址唯一标识一块内存空间。
  2. 指针的大小是固定的4/8个字节(32位平台/64位平台)。

3.指针是有类型,指针的类型决定了指针的±整数的步长,指针解引用操作的时候的权限。
4. 指针的运算。

提示:以下是本篇文章正文内容,下面案例可供参考

一、字符指针

在指针的类型中我们知道有一种指针类型为字符指针char*

1. 一般使用

#include<stdio.h>intmain(){char ch ='w';char* pc =&ch;*pc ='a';printf("%c", ch);return0;}

上述代码使用,char *指针把这个字符变量的地址放到这个char 指针中,然后通过对 pc解引用,找到字符**ch ,然后改变其中的值为a,我们来看一下打印的结果。这就是我们的一般用法.
在这里插入图片描述

2. 另一种方法使用

我们来看一个简单的代码

#include<stdio.h>intmain(){char* p ="abcdef";}

这段代码的意思是什么呢?这里是把字符串"abcdef"放到这个char*p的指针变量中了吗?呢我们就需要去想它能放的下吗?现在是在32位环境下,p指针变量是4个字节而"abcdef"是6个字节,在加上/0是7个字节,所以答案是存不下。所以这个代码的意思绝对不是把"abcdef"放到指针变量p中。其实这个代码的意思是把这个常量字符串"abcdef"首字符a的地址存放到指针变量p中。下面画图来说明(假设首字符地址是0x0012ff40)
在这里插入图片描述
如果你还是不敢相信,呢么我们可以使用 *p解引用访问这个字符串,其实访问的就是字符a 我们可以打印看看是不是.结果和我们想的一样
在这里插入图片描述
在有些初学者,不正确理解上述代码,就会出现下列问题。下面这个程序崩了,这是为什么呢?这是因为,这个字符串是一个常量字符串,常量字符串是不允许被修改的。
在这里插入图片描述
其实我们对这个代码,稍做优化可以防止出现这个错误。 这里就提示你编译错误。

#include<stdio.h>intmain(){constchar* p ="abcdef";*p ='w';}

在这里插入图片描述

3. 经典面试题

我们观察下列代码,会输出说明结果呢?

#include<stdio.h>intmain(){char str1[]="hello world.";char str2[]="hello world.";constchar* str3 ="hello world.";constchar* str4 ="hello world.";if(str1 == str2)printf("str1 and str2 are same\n");elseprintf("str1 and str2 are not same\n");if(str3 == str4)printf("str3 and str4 are same\n");elseprintf("str3 and str4 are not same\n");return0;}

这里最终输出的是:
在这里插入图片描述
这是因为: 这里str3和str4指向的是一个同一个常量字符串。C/C++会把常量字符串存储到单独的一个内存区域,当几个指针。指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始化不同的数组的时候就会 开辟出不同的内存块。所以str1和str2不同,str3和str4不同。

二、指针数组

指针数组是一个存放指针的数组

1. 一种使用

来看下面的一段代码 : 这里是3个变量,我们只需创建3个指针变量就可,但是如果变量10个 20个甚至更多呢?我们也需要创建对应的指针变量吗?呢我们就想到创建一个整型指针的数组,来存放变量的地址。

#include<stdio.h>intmain(){//int* arr[10];//存放整型指针的数组//char* ch[5];//存放字符指针的数组int a =10;int b =20;int c =30;int* p1 =&a;int* p2 =&b;int* p3 =&c;int* arr[3]={&a,&b,&c };//arr就是一个指针数组int i =0;for(i =0; i <3; i++){printf("%d ",*(arr[i]));//找到变量对应的地址,然后解引用就拿到了对应的元素}return0;}

2. 第二种使用

来看下面的一段代码 :

#include<stdio.h>intmain(){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 };//parr是一个指针数组int i =0;for(i =0; i <3; i++)//找到每一行{int j =0;for(j =0; j <5; j++)找到每一个元素
        {//printf("%d ", parr[i][j]);printf("%d ",*(parr[i]+j));依次加j,相当于找到每个元素地址,然后在解引用,找到并打印这个元素
        }printf("\n");}return0;

我们画图来解释:

在这里插入图片描述
我们分别有三个数组arr1 arr2 arr3,数组名表示首元素地址。然后我们把这三个数组名也就是首元素地址,分别存放到parr数组中,每一个类型都是int*
parr[0]–>arr1、parr[1]–>arr2、parr[2]–>arr3 分别对应。这时我们发现好像模拟出一个二维数组,先使用parr找到每一行,然后又可以找到每一个元素,然后就得出下面的打印结果
在这里插入图片描述

三、&数组名vs数组名

我们知道arr是数组名,数组名表示首元素地址。呢么&arr是什么呢?
来看下面的一段代码 :

#include<stdio.h>intmain(){int arr[10]={0};printf("%p\n", arr);//%p打印地址printf("%p\n",&arr);return0;}

运行结果如下:
在这里插入图片描述
可见数组名和&数组名打印的地址是一样的。难道这个两个意义相同吗?

我们在看下面的一段代码 :

#include<stdio.h>intmain(){int arr[10]={0};printf("arr = %p\n", arr);printf("&arr= %p\n",&arr);printf("arr+1 = %p\n", arr +1);printf("&arr+1= %p\n",&arr +1);return0;}

运行结果如下:
在这里插入图片描述
在这里arr类型是int* 当我们对其+1时由00B6FC70–>00B6FC74 整型指针+1跳过4个字节而&arr类型是int(*)[10],是数组指针类型,而数组的地址+1,00B6FC74–>00B6FC98 跳过了40个字节,跳过了整个数组的大小,所以 &arr+1 相对于 &arr 的差值是40.
**

通常情况下,我们说的数组名都是数组首元素的地址但是有2个例外:

**

1. sizeof(数组名),这里的数组名表示整个数组,sizeof(数组名)计算的是整个数组的大小
2. &数组名,这里的数组名表示整个数组,&数组名,取出的是整个数组的地址

四、数组指针

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

一个数组指针的使用:

#include<stdio.h>voidprint_arr1(int arr[3][5],int row,int col){int i =0;for(i=0; i<row; i++){for(j=0; j<col; j++){printf("%d ", arr[i][j]);}printf("\n");}}voidprint_arr2(int(*arr)[5],int row,int col){int i =0;for(i=0; i<row; i++){for(j=0; j<col; j++){printf("%d ", arr[i][j]);}printf("\n");}}intmain(){int arr[3][5]={1,2,3,4,5,6,7,8,9,10};print_arr1(arr,3,5);//数组名arr,表示首元素的地址//但是二维数组的首元素是二维数组的第一行//所以这里传递的arr,其实相当于第一行的地址,是一维数组的地址//可以数组指针来接收print_arr2(arr,3,5);return0;}

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

1 int arr[5]; arr是一个整型数组,有5个元素,每个元素是int类型的。
2 int parr1[10];parr1是一个数组,数组有10个元素,每个元素的类型是int ;所以parr1是**指针数组。
3 int (*parr2)[10];parr2先和 * 结合,说明parr2是一个指针,该指针指向一个数组,数组是10个元素,每个元素是int类型的,parr2是数组指针。
4 int (*parr3[10])[5];parr3和[]结合,说明parr3是一个数组,数组是10个元素,数组的每个元素是什么类型呢?是一种数组指针,类型是int( * )[5],该类型的指针指向的数组有5个int类型的元素。
以上就是指针的一部分内容, 🌟Hello world 我们下期见!


本文转载自: https://blog.csdn.net/lsh0414/article/details/123421718
版权归原作者 Dream_辉辉 所有, 如有侵权,请联系我们删除。

“【详解C语言指针】(关于字符指针,数组指针,指针数组等)”的评论:

还没有评论