字符指针与字符串、多级指针以及指针数组

本篇我主要写了以下四点关于指针的问题

  • 字符指针与字符串
  • 指针数组
  • 多级指针
  • void 和const 指针

首先感谢大家的观看,如果大家能有所收获,那真是荣幸之至

一、字符指针与字符串

  • C语言通过使用字符数组来处理字符串,通常,我们把char数据类型的指针变量称为字符指针变量。字符指针变量与字符数组有着密切关系,它也被用来处理字符串。

  • 初始化字符指针是把内存中字符串的首地址赋予指针,并不是把该字符串复制到指针中,此时可以通过指针来修改字符串的内容

char  str[] = “Hello World”;
char  *p = str;

printf("&str=%p %s\n",&str,str); 
*p='h'; *(p+1)='E';
printf("p=%p %s\n",p,p);

这里是引用
由此可以看出,p指向的str的首地址,可以根据p指针来修改字符串的值。如果有人对上述用*p修改有疑问,可以参考我上一篇博客,C语言指针简介与相关的难点

非常重要
  • 在C编程中,当一个字符指针指向一个字符串常量时,不能修改指针指向的对象的值。当你直接将字符串赋值给指针时,该字符串会被认为是常量,会被存放在静态区域,所以此时不能修改。
char  *p = "Hello World"; 
*p = 'h';    //  错误, 字符串常量不能修改
char *p1 = "Hello World";
char *p2 = "Hello World";

printf("%p\n",&"Hello World");
printf("&p1=%p p1=%p %s\n",&p1,p1,p1);
printf("&p2=%p p2=%p %s\n",&p2,p2,p2);

在这里插入图片描述
由结果可知,两个不同指针被赋予相同的字符串被认为是一个常量存放在静态区,两指针都指向的是该常量的地址

  • 使用指针完成字符串的链接操作
#include<stdio.h>

int main(){
	char ch[50] = "Hello";
	char *p = "World";
	
	int i = 0;
	while( ch[i]!='\0')  //找到原字符串的末尾 
		i++;
	while( *p != '\0'){  //链接 
		*(ch+i) = *p;
		i++; p++;
	}
	*(ch+i) = *p;   //在字符串末尾加上结束符	
	puts(ch); 	
}

二、指针数组

  • 所谓指针数组是指由若干个具有相同存储类型和数据类型的指针变量构成的集合
  • 指针数组的一般说明形式:
    <数据类型> *<指针数组名>[<大小>];
    指针数组名表示该指针数组的起始地址
//声明一个指针数组:
 double  * pa[2] ,a[2][3];

//把一维数组a[0]和a[1]的首地址分别赋予指针变量数组的数组元数pa[0]和pa[1]:
 pa[0]=a[0] ;       // 等价pa[0] = &a[0][0];
 pa[1]=a[1];        // 等价pa[1] = &a[1][0];
 
//此时pa[0]指向了一维数组a[0]的第一个元素a[0][0], 而pa[1]指向了一维数组a[1]的第一个元素a[1][0]。
//则a[0][1]就可以用  p[0]+1表示;

在这里插入图片描述

指针数组名是个什么指针?
int  *p[2];
q =  &p[0] ;   //q的定义是什么?

由指针数据的定义的格式可知指针q的定义如下: <数据类型> * q
该<数据类型>取决于目标的类型,及p的类型,而p的类型为int *所以q的定义为: int ** q;这是一个二级指针。

三、多级指针

  • 多级指针的定义
    把一个指向指针变量的指针变量,称为多级指针变量
    对于指向处理数据的指针变量称为一级指针变量,简称一级指针
    而把指向一级指针变量的指针变量称为二级指针变量,简称二级指针

  • 二级指针变量的说明形式如下
    <数据类型> ** <指针名> ;

  • 多级指针的运算

    • 指针变量加1,是向地址大的方向移动一个目标数据。类似的道理,多级指针运算也是以其目标变量为单位进行偏移。
    • 比如,int **p;p+1移动一个int *变量所占的内存空间。再比如int ***p,p+1移动一个int **所占的内存空间。
int a[] = {3, 6, 9};
int *p[2] = {&a[0], &a[1]};
int **q;
q = &p[0];  //等价为q=a; 

printf("%d %d %d\n",a[0],*p[0],**q);  //a[0]的表示方法 
printf("%d %d %d\n",a[1],*p[1],**(q+1));//a[1]的表示方法
printf("%d %d %d\n",a[2],*(p[1]+1),*(*(q+1)+1));//a[2]的表示方法

在这里插入图片描述

在这里插入图片描述

  • 由图可知,p[0],p[1]存的是a[0],a[1]的地址,所以p[0]表示a[0]的存的值,q存的是p[0]的地址,故q就表示p[0]的值,及a[0]的地址,所以**q就表示a[0]的值。
  • a[3]的地址可由a[2]的地址+1表示,即p[1]+1;同理,p[1]的地址可由q+1表示。所以a[3]的地址等价于 *(q+1)+1。
  • 不要问我为什么a[3]不能用q+2表示,这说明你还是没有理解,上面这个图的结果是从右往左推出来的,而不是从左往右推的,实在理解不了,自己画个图理解下或者自己编程看看q+2的地址是啥

四、void和const指针

1. void指针

是一种不确定数据类型的指针变量,它可以通过强制类型转换让该变量指向任何数据类型的变量
一般形式为: void * <指针变量名称> ;

对于void指针,在没有强制类型转换之前,不能进行任何指针的算术运算。

2. const修饰指针

关于const修饰,总之记住一句话:const修饰谁,谁不能改变。

1)常量化指针目标表达式

  • 一般说明形式如下:

const <数据类型> * <指针变量名称>[= <指针运算表达式>] ;

常量化指针目标是限制通过指针改变其目标的数值 ,但<指针变量>存储的地址值可以修改

int  m=10; 
const int *p =  &m;
p = &n;  //right
(*p)++;  //error, const修饰*p ,所以*p不能改

2)常量化指针变量

  • 一般说明形式如下:

<数据类型> * const <指针变量名称>[= <指针运算表达式>] ;
使得<指针变量>存储的地址值不能修改。但可以通过*<指针变量名称> 可以修改指针所指向变量的数值

int m = 10;
int * const q = &m ; 
(*q)++;    //right
q = &m;   //error ,只能在定义时初始化

3)常量化指针变量及其目标表达式

  • 一般说明形式如下:

const <数据类型> * const <指针变量名> = <指针运算表达式> ;
常量化指针变量及其目标表达式,使得既不可以修改<指针变量>的地址,也不可以通过*<指针变量名称>修改指针所指向变量的值

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
指针数组可以存放字符串数组。在C语言中,一个指针数组可以被定义为一个数组,其中每个元素都是指向字符串指针。每个指针指向一个字符串常量或字符数组的首地址。通过指针数组,我们可以在内存中存储多个字符串,并通过指针来访问这些字符串。这样做的好处是可以方便地对字符串进行操作和处理,比如查找、排序等。需要注意的是,指针数组中的每个指针元素都需要分配足够的内存空间来存放对应的字符串。引用 [1和提供了关于内存中存储字符串的相关信息,而引用给出了一个使用字符数组存放字符串的示例。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [用一维字符数组存放字符串](https://blog.csdn.net/weixin_31885875/article/details/117020399)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [C++字符数组存放字符串 | 字符指针变量](https://blog.csdn.net/weixin_48669767/article/details/111352405)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值