栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言犄角旮旯的知识之数组与函数

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言犄角旮旯的知识之数组与函数

目录

数组

不存在的数组

数组的地址

字符型数组

函数

函数的注释

函数与数组

一二维数组做函数的形参与实参


数组

首先单独讲一下数组

不存在的数组

数组实在是太奇妙了,有些老师会介绍说,数组有一维数组、二维数组、三维数组······,也有些老师会说数组其实只有一维的,其他都是一维数组的嵌套。而笔者认为,C语言中重来没有数组,只有指针,或者说数据地址(虽然这么说优点无赖的感觉)。举个例子,对于int a[2];中a[1]来说,大部分老师会怎么解释呢,没错,老师都会说这是a数组里的第二个元素,但是你可以去尝试输出printf("%dn",1[a]);,会有什么情况呢,会报错吗,答案是不会,而且完全正确!!就连你输出的值与a[1]也别无二般,但你总不能说这是一个数组名叫“2”的数组中第二个元素吧。这其中到底有什么玄关呢,笔者先买个关子,等在数组与指针那一篇里面再详细解读。

我们先来看看数组的其他知识

数组的地址

当我们定义一个数组时,数组的首地址就已经确定,且不能更改,如  int a[10];  这个数组的首地址就是a,而数组的下标则是对a地址的偏移量。一个数组的地址是连续的。随意更改数组首地址将会报错。

字符型数组

这里有三个字符型数组要注意的点

当说一个数组的长度时,说的就是这个数组的元素个数,但如果是字符型的数组,最后会加上一个“/0"字符(只会在字符串后面自动加,其他的如char a[] = {'a','b'}是不会加的,用sizeof和strlen求都是2)。使用sizeof求长度时,会计入这个字符,长度加一,使用strlen求长度时,不会计入。

根据以上,请问以下两个定义是否有错

char a[5] = {"abcde"};
char a[5] = {'a','b','c','d','e'};

答案是第一个是错的,第二个是正确的。为什么呢,因为字符串后面会自动加一个字符'/0',所以第一个定义实际上有6个字符,超出数组大小,而第二个定义不会加'/0',所以还是5个字符。

当有  char a[] = {0,1,48};的字符型数组被定义时,初始化中,像这样直接写的是数字的,其实记录的是对应字符的ASCII码值,如a[2]其实是ASCII为‘48’的那个字符。想要存储字符,就必须有单引号引起来。

我们再看一组就能更加深入理解sizeof与strlen这两个关键字了

char s[6]={'2','3','','6','5'} ;
printf("%dn",sizeof(s));        //输出 “2”

char s[6]={'2','3','','6','5'} ;
printf("%dn",strlen(s));        //输出  “6”

char s[6]={'2','3','','6','5','8'} ;
printf("%dn",sizeof(s));        //输出  “6”

可以看出,sizeof会在数组未满时,或者字符串后面自动计数上“/0”结束符,并且不会因为中间遇到“/0”结束符就中止计数,会将所有元素个数计入;而strlen会遇上“/0”就会中止计数,并不计入“/0”结束符。

连续定义数组空间分配问题

两个或多个数组连续定义的时,一般会连续分配空间,不止是数组,当我们连续定义变量时,大概率都会连续分配空间,而当我们不注意空间大小时,可能数据会溢出到其他变量里。

让我们判断一下一下程序会输出上面呢?

char s1[8];
char s2[8] = {"abcde"};
strcpy(s1,"0123456789");    //strcpy:将后面的字符串复制到前面的变量里
printf("%sn",s1);
printf("%sn",s2);

答案是:

0123456789
89

因为s1与s2的内存分布是连着的,而strcpy不会考虑是否越界,所以字符“89”将越界到s2中去,这也导致s1中没有了结束符,所以会一直读到有结束符的地方,再strcpy完后,也自动加上“/0‘结束符,也就是s2[8] = {'8',9','','d','e'}。(当然,有些编译器可以不会出现这种问题)

函数

函数的注释

初学者可能还没有深刻的认识,但已经从事开发的程序员来说,这一点是非常重要的一点。毕竟程序员都讨厌两种人,一种是不写注释的人,还有一种就是让自己写注释的人。很荣幸,我也成了其中之一。所以就让我们在现在做起,做一个会写注释的好程序员吧。

对于语句的注释,那当然就是表达清晰即可,但对于函数的注释,是要很规范的,这样,别人看你的代码和你看别人的代码都能节约不少时间,格式如下:

 

这里涉及到了形参,其实对应的还有一个实参,他们的区别是:

形式参数:定义函数时,指定的参数

实际参数:调用函数时,指定的参数

函数与数组

一二维数组做函数的形参与实参

一维数组做函数的形参与实参

int a[10];

void function(int a[],int n)  //形式参数

function(a,10)  //实际参数

一维数组做函数的形参与实参

int a[5][10];

void function(int a[][10],int n)  //形式参数

function(a,5)  //实际参数

到这里,数组与指针的关系就介绍完啦,如果对你有帮助的话,可以点个赞收藏一下哦。后续这个专栏也会出指针与数组和函数的相关文章,相信我,那个才是真的有趣!!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1030919.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号