指针(二)字符串指针的理解与应用

熟话说,工欲善其事,必先利其器。看了一些实例代码后,发现还是有不理解的指针语法。所以对于c语言指针,打算做一个详细的了解,之前对于c语言指针,主要是建立在一个基础数组的理解,接下来希望通过自己的理解,用自己的语言写出更加容易让人理解的文档。

1.关于指针的定义
指针具体是什么呢?
指针是存储一个内存的内存地址变量,简单的说就是,内存就像是一本书,而内存中的数据就像书内的文字,指针可以理解为目录之类的纸上写的是具体书内的某一页码某一行数,当你依靠指针指向的内存单元,你就能找到内存单元上存储的具体内容。

关于字符串指针赋值问题,以下都为个人理解与实验所得,仅供参考,具体情况请自行验证。

归纳总结举例如下:
1. 对于一维指针char型,即char *p:
例:char ss[]=”hello”;char *p;p=ss;

对于ss,&ss,*ss,它们的具体意思从代码结果来看
ss:字符串的首地址
*ss:字符串的首地址上的char值
&ss:字符串存储地址,故与ss相等

对于指针*p,关于p,&p,*p它们各自是指什么意思呢?
p:指向的字符串的首地址
*p:指向的字符串的首地址上的值
&p:存储该指针的地址

char ss[]="hello";
    char *C;
    C=ss;
    char *p_C2=NULL;
    p_C2=C;
    printf("ss(x)=0x%x\tss(s)=%s\t*ss=%c\n\n",ss,ss,*ss);   printf("C=%s\t\t&C=0x%x\t\t*C=%c\np_C2=%s\t&p_C2=0x%x\t*p_C2=%c\n\n",C,&C,*C,p_C2,&p_C2,*p_C2);

显示结果为

2.对于二维char型指针,即char **p:
现以之前看到的一个经典指针题为例:

char *str[]={"welcome","to","Fortemedia","Nanjing"};
printf("str(s)=%s\tstr(x)=0x%x\n",*(str+1),str);
char**p=str+1;
char *pp;
pp=*p;
printf("*p(s)=%s\tp(x)=0x%x\t**p(c)=%c\n",*p,p,**p);
printf("===>  pp=*p\n");
printf("*pp=%c\tpp=%s\t&pp=0x%x\n",*pp,pp,&pp);
str[0]=(*p++)+2;
str[1]=*(p+1);
str[2]=p[1]+3;
str[3]=p[0]+(str[2]-str[1]);

现对str,*str进行理解:
这里对于char *str[]我们可以看做char *str[4];

*str[0]=”welcom”
*str[1]=”to”
*str[2]=”Fortemedia”
*str[3]=”Nanjing”

str为该二维字符串的首地址,即str[0],
str+1其实是str的首地址+sizeof(char *)故为str[1],此时str[1]应该为字符串to的首地址
*str,我们已经知道str是当前字符串的首地址,故*str即为首地址上的值,即为字符串的第一个字母。

对于char **p=str+1;
我们知道,str+1现指的是to这个字符串的首地址,现在把char **p指向to的首地址,那根据一维数组指针中char *p_C2=C时,p_C2是C指针指向的字符串的首地址,那这里*p就为当前str+1代表的地址,即为字符串to的首地址。那p呢,同理推导,对于一维指针p,我们有提到&p是指当前指针的存储位置,那对于二维指针p即为当前指针的存储位置。

我们具体来分析这道题:
str[0]=(*p++)+2;
*p已经说过,是指当前指针字符串,即str+1为首地址的字符串,即to
因为是后++,故分解开来应该是
str[0]=*p+2;
*p++;
对于str[0]=*p+2;
*p的单位是char ;那*p的单位是char
现在*p的位置是to字符串的首地址,加两个单位的char型内存大小,则此时*p的位置为指向‘\0’的内存位置,故str[0]此时指向‘\0’
此时*p ++,由于后置++运算符优先级高于 *p故,拆分开来即为p++, *p。
p指的是存储当前字符串to首地址的内存地址,故p++即为存储当前字符串后一个字符串的首地址的内存地址,即当前自增1后p指的是”Fortemedia”的首地址的内存地址,即此时str[2]的首地址(深刻理解,与最后一问有关!)

然后str[1]=*(p+1);
p再加1,此时p+1指向存储字符串”Nanjing”的首地址的内存块的内存地址,故*(p+1)即str[1]指向的是”Nanjing”的首地址,故输出的str[1]为Nanjing

接着看str[2]=p[1]+3;
由上知,p指的是Fortemedia字符串首地址所在的内存块地址,则p[1]实则是等于p+1的,故p[1]+3即为Nanjing字符串首地址N所在地址加三个单位,即指向j所在位置,故输出的str[2]为jing

最后 str[3]=p[0]+(str[2]-str[1]);
p[0]指的是p即为str[2]的首地址,str[2]指的是j所在的位置地址,str1指的是N所在的位置,故str[2]-str[1]即为3,此时地址为g所在地址位置。

以下为实验代码即相应结果:

char *str[]={"welcome","to","Fortemedia","Nanjing"};
    printf("str(s)=%s\tstr(x)=0x%x\n",*(str+1),str);
    char**p=str+1;
    char *pp;
    pp=*p;
    printf("*p(s)=%s\t*p+1=%s\t*(p+1)=%s\t(*p)+1=%s\tp(x)=0x%x\t**p(c)=%c\tp+1=0x%x\n",*p,*p+1,*(p+1),(*p)+1,p,**p,p+1);
    str[0]=(*p++)+2;
    str[1]=*(p+1);
    str[2]=p[1]+3;
    str[3]=p[0]+(str[2]-str[1]);
    printf("str[0]=%s\tstr[1]=%s\tstr[2]=%s\tstr[3]=%s\n",str[0],str[1],str[2],str[3]);

参考文章

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值