杂谈指针与数组
作为一个计算机菜鸟,从喜爱电子游戏到大学里选择了计算机专业。从一直以为计算机专业就“玩电脑”。直到第一节C语言课……博主才发现这个世界原来不是我一直想的那样。
转眼博主也即将毕业了,从当初嚣张的新生慢慢变成了一个话少脸红的准程序猿。这过程具体的就不怎么讲了……
今天是博主在CSDN的第一篇文章,想了想,就写写数组与指针吧。
咳咳咳……在写之前我要说一件事,博主是菜鸟。写错了请大家纠正。
数组篇
数组我相信大家都不陌生,我们C语言时,很早就会接触到数组。数组,说白了就是一堆相同类型的数据的集合。我们大家都会去定义。
例如:int a[100] 100个int型数据的集合
char a[10] 10个字符型数据的集合
我写的这两个数组,它们都是一维数组。说起一维数组,自然会有人说到二维数组甚至三维数组。
例如 int a[2][2] 这是一个二维数组,它有两行两列(PS:二维数组的行可以不写,但列不可以。)。
int a[2][2][2] 这是一个三维数组。
数组名是指针常量,不可以自加运算。关于数组有以下一些重要内容。
1:一维数组的数组名是一维数组首元素的地址。&a才是一维数组的地址。
2:二维数组的数组名是二维数组中第一个一维数组的地址。*a是(*是取值运算符,作用是根据指针变量名对应的内存空间存储地址找到对应空间的值)二维数组中第一个 维数组首元素的地址。自然而然**a就是二维数组中第一个一位数组首元素的值。
3:三维数组的数组名三维数组中第一个二维数组的地址。以此可以类推,**a为三维数组中第一个二维数组中第一个一维数组的首元素地址。(听着有点儿混乱了…没关系,慢慢想,能想通)。
指针篇
说指针前我们先介绍C语言中的一个操作符:sizeof。
这个操作符的作用,百度百科给出的解释是返回一个对象或者类型所占的内存字节数(对象属于面向对象语言的的范围,我们先不管)。
现在我们来用这个操作符。
看以下代码:
int main()
{
int a[2];
char *p = NULL;
printf(“a=%d\n”,sizeof(a));
printf(“p=%d\n”,sizeof(p));
return 0;
}
输出结果:
a=8
p=4
如果我们把定义的char *p换成int *p或者long *p。我们的对于p的输出都是4。从这里我们要知道一个概念,指针是一种变量,叫指针变量。在32位系统中它占用4个字节。
指针可以指向函数,也可以指向变量。很多时候我们会用到指针,指针的好处非常的多。大家都说指针是C语言的精华。至于他精华到哪里了,这个我们要慢慢的来说。
举个例子吧
int a[4];
int *p = a;
这个例子中我们的指针p指向了数组a。我们把指向数组的指针也叫做数组指针(保存指针的数组叫指针数组,不要混乱)。我们写一个输出数组a的代码。
int i; //中间变量
for(i = 0; i < 4; i++)
{
a[i]= i*2;
printf(“a[%d] = %d\n”,i,a[i]);
}
除了这样写,我们还可以写成:
for(i = 0; i < 4; i++)
{
a[i]= i*2;
printf(“a[%d] = %d\n”,i,*(p+i));
}
他们得到了同样的结果。这是就是我们用数组名和用指针两种办法去遍历输出。
我们讲*(p+i)改成*(p++),同样可以输出结果。
这就是我们之前说的,一维数组名是一维数组的首地址,但是一维数组名是指针常量,不能进行自加或者改变。但是指针就可以。这里如果可以,也当做指针灵活性的表现吧。
下面我要说说指针和数组的不同。
1:数组名是指针常量,指针式变量。
2:数组是静态分配内存空间的,并且是一段连续的内存空间。而指针指向的内存空间是动态分配的,不一定连续的。从这里我们看出,数组对空间利用率很低,扩展性很差。我静态分配100个空间,存了10个数,这就是浪费。我存101个数,就是数组越界。而指针就不同了,动态分配,有多少分配多少,少了就再分配。
3:数组是直接访问内存空间的,而指针是间接访问的(通过地址)。从这里我们看出,指针有安全隐患,使用的不当,会造成内存泄露等问题。
4:我们要注意一下,像char *p = “zhangquandan”;这样的字符串,是保存在内存的全局变量区中的only read中。不可以修改。
5:数组名是指针常量,当数组作为形参时时,会默认转变为指针变量。所以我们在函数中式可以对其自加操作的。(PS:对于传参问题过些日子我会单独写一篇文章,这是一个很有意思的东西)。
指针的内容其实还有很多。不是我一个菜鸟一篇文章能写完的。我写这个其实是想说说指针与数组的相似之处与不同之处。最后,祈祷自己明年这个时候,能成大神,并寻得一份好工作。同时能结交更多的朋友。女朋友最好了
画匠Creams