[C计划—01] 数组与指针的复习

写在前面

最近决定重新复习一遍C语言,感觉大学前三年代码能力还是不好,决定复盘一下C语言和数据结构,把比较重要的点记录下来,最后希望可以做点好玩的小项目(五子棋、贪吃蛇之类的)吧。我把这取名为 “ C计划 ”,希望可以坚持下来。

最近复习到数组、字符串和指针,当时学的时候就感觉是语法重点,在这里进行一下汇总,有不对的地方希望各位同学指正补充,一起进步!

数组

数组的定义

数组的定义很平常,对于单纯的纯数组,定义要包括:数组的数据类型、数组名(地址)、数组元素个数。如果 [ ] 内未声明元素个数,则需要直接完成初始化,否则会报错。原因是计算机不知道要为数组开辟多大的存储空间。

下面展示一些 数组定义方式

    float candy[365]; /* 内含365个float类型元素的数组 */ 
    char code[12]; /*内含12个char类型元素的数组*/ 
    int states[50]; /*内含50个int类型元素的数组 */
    
    int m = 8; int n = 7;
    float a1[5]; // 可以 
    float a2[5*2 + 1]; //可以 
    float a3[sizeof(int) + 1]; //可以 
    float a4[-4]; // 不可以,数组大小必须大于0 
    float a5[0]; // 不可以,数组大小必须大于0 
    float a6[2.5]; // 不可以,数组大小必须是整数 
    float a7[(int)2.5]; // 可以,已被强制转换为整型常量 
    float a8[n]; // C99之前不允许 
    float a9[m]; // C99之前不允许
    
    int states[]; /*无法通过,要跟python区分开*/
    int states[]={012}; /*没问题*/

数组的初始化

数组的初始化需要注意的点是:

  • 如果对某一数组没有进行任何初始化,那么该数组里存储的是“垃圾值”。
  • 如果对某一数组进行部分初始化,那么计算机自动把剩余的位初始化为 0。
  • 如果未声明数组元素个数,那么在定义时一定要进行初始化,否则,计算机不知道要为这个数组开辟多大的存储空间,编译无法通过。
  • 在引用时注意下标,数组初始索引为0。

C99 增加了一个新特性:指定初始化器(designated initializer)。利用该特性可以初始化指定的数组元素。例如,只初始化数组中的最后一个元素。对于传统的C初始化语法,必须初始化最后一个元素之前的所有元素, 才能初始化它;而C99规定,可以在初始化列表中使用带方括号的下标指明待初始化的元素。

int arr[6] = {0,0,0,0,0,212}; // 传统的语法 
int arr[6] = {[5] = 212}; // 把arr[5]初始化为212 

对于一般的初始化,在初始化一个元素后,未初始化的元素都会被设置为0。

多维数组

多维数组定义要包括:数组的数据类型、数组名(地址)、数组元素行和列

float rain[5][12] = ; // 内含5个数组元素的数组,每个数组元素内含12个 float类型的元素

5行12列的数组
当然,我们可以继续定义高维的数组。

float arr[5][12][12] ; // 内含5个数组元素的数组,每个数组元素内含12个 float类型的元素

后面做项目可能会用到多维数组比较多,到时候再说。

指针

指针提供一种以符号形式使用地址的方法,指针的声明是要用到间接运算符‘ * ’。‘ & ’取地址,‘ * ’取所在地址的变量值。

int *ptr; / *定义*/

假设一个指针变量名是ptr,可以编写如下语句:

ptr = &pooh; // 把pooh的地址赋给ptr 

对于这条语句,我们说ptr“指向”pooh。ptr和&pooh的区别是ptr是变量, 而&pooh是常量。或者,ptr是可修改的左值,而&pooh是右值。还可以把ptr 指向别处:

ptr = &bah; // 把ptr指向bah,而不是pooh 

现在ptr的值是bah的地址。

一维数组与函数指针

  • 数组的名称就是数组的首地址,在我们的系统中,是按字节编址的。int类型占4个字节,我们对指针加一,指向的是下一个数组的元素的地址,而不是指向下一个字节的地址。
	int *sp;
	int arr[6] = {1,2,3,4,5,6};
	sp = arr;
	for (int i = 0; i < 6; i++)
	{
		printf("第%d个元素%d,他的地址为%d\n", i,*(sp+i),sp+i);
	}
  • 函数传递的参数也可以是指针,比如下面这个程序
int sum(int* ar) // 相应的函数定义 
{
	int i; int total = 0; 
	for (i = 0; i < 10; i++) // 假设数组有10个元素 
		total += ar[i]; // ar[i] 与 *(ar + i) 相同 
	return total; 
}
  • 指针本身也是有地址的。因此&sp是指向sp的指针,而sp是指向arr的指针。
int main()
{
   int *sp;
   int *a;
   int arr[6] = {1,2,3,4,5,6};
   sp = arr;
   for (int i = 0; i < 6; i++)
   {
   	a = sp + i;
   	printf("第%d个元素%d,这个元素的的地址为%p,当前指针的地址为%p.\n", i,*a,a,&a);
   }
}

切记:创建一个指针 时,系统只分配了储存指针本身的内存,并未分配储存数据的内存。因此, 在使用指针之前,必须先用已分配的地址初始化它。下面代码是不允许的。

int main()
{
   int *sp;
   *sp = 5; /*这是不允许的*/
}

多维数组的指针

如何声明一个指针变量pz指向一个二维数组(如,zippo)?在编写处理类似zippo这样的二维数组时会用到这样的指针。把指针声明为指向int的 类型还不够。因为指向int只能与zippo[0]的类型匹配,说明该指针指向一个 int类型的值。但是zippo是它首元素的地址,该元素是一个内含两个int类型 值的一维数组。因此,pz必须指向一个内含两个int类型值的数组,而不是指 向一个int类型值,其声明如下. 注意与第二行的区分。

	int (* pz)[2]; // pz指向一个内含两个int类型值的数组
	int * pax[2]; // pax是一个内含两个指针元素的数组,每个元素都指 向int的指针

这一部分还是比较难理解的,这里直接放上《C primer plus》中的解释,个人感觉解释的蛮清楚的。

在这里插入图片描述
在这里插入图片描述

关于指针的兼容性和多级解引用,在《C primer plus》中有着很多的介绍,可能学得还不够深入,觉得书中介绍的情况在工程生活中有点“刁钻”,先了解了一下,等遇到的时候再来细细研究一下。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值