黑马程序员——指针与数组、字符串、字符串数组、指针函数

------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------


天在复习的时候碰到这样一段代码:

<span style="font-family:Microsoft YaHei;font-size:14px;">#include<stdio.h>
char *day_name(int n){
	char *name[]={ "Illegal day",
                    "Monday",
                    "Tuesday",
                    "Wednesday",
                    "Thursday",
                    "Friday",
                    "Saturday",
                    "Sunday"};
	return ((n<1||n>7) ? name[0] : name[n]);
}

int main(){
	int i;
	scanf("%d", &i);
        printf("Day No:%2d-->%s\n", i, day_name(i));
	return 0;
}</span>

来看着是挺明白。第一行创建了一个返回值为指针的函数,函数的形参是整形,即n。

在函数内部创建了一个字符串数组,分别是星期的英文,数组的第一位还考虑到了输入错误的情况,非常周到。

剩下的就简单了,main函数里读取一个 i ,之后输出对应的"星期i"。


但是事情就怕人自己琢磨,尤其是概念很容易混淆的时候。

我首先考虑,为何一定要使用指针函数? 

我直接char day_name(int n)行不行?

好的,那我把name[]前面的*也去掉,表示一个由字符串组成的数组不就行了,也不需要指针。

但是我改完之后发现错误的非常厉害。不论我怎么修改也不得不使用指针函数,name[]前也一定有“*”。

我问自己:

char a[] = “hello world”;

char *a[] = {"hello world"};

有什么区别?

竟然一下子就把自己问倒了。真是感觉被泼了一盆冷水。赶紧收起散漫的姿态,找书。

那么,从根源说起吧 。

什么是数组

组是一种容器,有什么特点呢?

1.所有元素都是相同类型

2.一旦创建,大小固定

3.元素是有序的

创建一个由数字构成的数组:

int a[] = [1,2,3,4,5,6];

注意是中括号,很多时候都是因为对符号不敏感,而模糊了基本概念,这也为我之前犯下的错误埋下伏笔。

什么是字符串

名思义,由字符组成的一串数据啊。

那么平时是怎么创建的呢?有很多种方法:

char str[] = "Hello World!";

char str[8] = {'h','e','l','l','o'};    这里未赋值的位置用空格填充。

char str[] = {"Hello World!"};

到这里可以看出,其实字符串的本质,是由每一个小字符,用数组的方式组成的一串数据。

在打印的时候就有体现了:

比如我们在使用printf函数的时候,%s 和 %c 又有什么样的区别呢?

<span style="font-family:Microsoft YaHei;font-size:14px;">char str[] = "Hello World!";
printf("%c\n",*str);
printf("%s\n",str);</span>

str
既可以理解为字符串的名称,也可以理解为一个指针,指向字符串开始的内存地址。

%s 打印的是从指针开始位置直到结束(\0)之间所有的字符。

%c 打印的是指针当前所指位置的一个字符。

可以自己玩一下,来确认我们的推理是否正确。(虽然上课老师讲过,不过自己确认之后记忆岂不是更深刻?)


<span style="font-family:Microsoft YaHei;font-size:14px;">char str[] = "Hello World!";
	printf("%c\n",*str+5);
	printf("%s\n",str+5);</span>

我们让指针向后移动,发现果然,打印的结果也符合我们的推论。


在已经完全回忆起了字符串的相关知识。

那么,问题又来了挖掘机哪家强?

char *str[] = {};到底是什么

个时候就体现了,对概念的敏感程度了,很多时候我们会对学到的基础知识抱着一种,“反正我会用就行呗,我知道那么清楚干什么?”

这样是不行的,虽然现在扣概念时候看起来像鸡蛋里挑骨头。但基础不稳如何学深学透?

首先,分析下,char * 是什么意思?对,是一个指针。这我们都能看出来。

别急,继续分析,这是一个指向字符串的指针。有没有豁然开朗?

如果没有也别急,后面的[]看着想不想是一个数组?里面放着数字,代表数组的长度。

那么这个“数组”是什么组成的呢?

没错,是指针,是指向字符串的指针 ,即(char *)。

至此,一切水落石出了。怪不得,char str[] = {"abc","bcd"}; 是错误的。

因为,虽然同样创建一个数组,但数组的每一个单元是“char”类型吗?还记得数组 最开始的int ,char的意义吗?

对!它定义了数组内部每一个单元的数据类型。

回到我们最开始的代码段:


<span style="font-family:Microsoft YaHei;font-size:14px;">char *name[]={ "Illegal day",
                    "Monday",
                    "Tuesday",
                    "Wednesday",
                    "Thursday",
                    "Friday",
                    "Saturday",
                    "Sunday"};</span>

这段什么意思呢? 

定义了8个指针组成的数组,每个指针各各自指向一个字符串。

函数day_name的返回值是什么?

从return这一行可以看出,返回name[0] 这种类型,这正是name数组内部的第一个单元,它是一个指向字符串的指针!

至此,一切都可以连起来了,也解释了为什么函数写作 char *day_name(int n) 而不能改成 char day_name(int n)








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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值