C语言中数组的七十二变

对于数组的学习要掌握这些基本的内容:



一.学会数组的定义和初始化的方式,包括一维数组,二维数组,三维四维等等。
1.char arr1[] = "abc";//4
  2.char arr2[] = {'a', 'b', 'c'};//3
这两种初始化方式中第一个数组arr1中有4个元素,而arr2中只有3个元素,
因为使用字符串"abc"给arr1初始化会自动加上一个'\0',因此有四个元素。




二.数组中的下标操作符的活用,理解下标操作符的用法。
下面从下列代码中解析下标操作符的活用
//int main()
//{
//	int arr[] = {1,2,3,4,5,6,7,8,9};
//	int i = 0;
//	//int *p = &arr[0];//和int *p = arr;的作用是一样的
//	int *p = arr;//
//	for(i=0; i<sizeof(arr)/sizeof(arr[0]); i++)//补充一个知识点,sizeof(arr)返回的是arr这个整个数组所占内存的大小
                                                   // sizeof(arr[0])代表数组中第一个元素的占内存大小,sizeof(arr)/sizeof(arr[0])
						   //  得到的就是元素的个数                                          
//	{
//		printf("%d ", arr[i]);//因为数组arr[0]是第一个元素,所以arr[i]代表数组中第i+1个元素的值
//		printf("%d ", i[arr]);//比较不常见的用法,与arr[i]一个意思
//		printf("%d ", *(arr+i));//一维数组中的数组名是首元素的地址,因此arr也是一个指针类型,*(arr+i)代表第i+1个元素中的值
//		printf("%d ", *(p+i));//代表第i+1个元素中的值
//		printf("%d ", *(i+p));//代表第i+1个元素中的值
//		printf("%d ", i[p]);//代表第i+1个元素中的值
//		printf("%d ", p[i]);//代表第i+1个元素中的值
//
//	}
总结:arr[i]等于*(arr+i),[]和*的功能都是把地址中的值拿出来,同时i[arr]等于arr[i],这个性质要记住。




三.数组名与数组的关系。
如果定义一个一维数组:
int a[2];
a的值等于&a[0]的值,a代表的是首元素的地址
&a的地址虽然与a和&a[0]相同,但是它代表的
整个数组的地址。
如果定义一个二维数组:
int a[2][2];
&a等于a和a[0]和&a[0][0]的值
但是&a的地址代表整个二维数组的地址
a代表第一排数组的地址,&a[0]与a是一个意思
a+1代表第二排地址的数组
a[0]代表第一排数组的首个元素的地址
a[0][0]代表第一排数组首个元素的值






四.数组中内存的储存方式。

如果定义一个二维数组

 1.int a[2][2]={1,2,3,4};
是否可以按2中这样理解,把1中的数组看成2中的形式,aa0看成1中二维数组的第一排的元素,aa1看成1中二维数组的第二排元素。
 2.
int *a[2]; 
int aa0[2]={1,2};
int aa1[2]={3 , 4};
a[0]=aa0;//把第一排的数组中的首地址给指针类型数组a[0]
a[1]=aa1;//把第二排的数组中的首地址给指针类型数组a[1]
如果初始化值相同的话
2中的 *a代表 a[0],     *a[0]又代表数组 aa0中的 首个元素   ,   那么 *(*a)也代表 aar0首个元素的值

类比1*(*a)也代表第一排首个元素,好像二维数组可以如2中转化为一维数组来理解,但是实际上是不可以这样理解的,

因为定义一个二维数组后,实际内存中储存关系是连续的,而2中这样定义数组不一定是

连续的,因此不能这样去理解。






五.函数中怎么调用数组。
int a[10];
void arraysUser(int *p)
{
...
}
要在arraysUser函数中使用数组a
arraysUser(a);//这样写即可,意思为把数组的首地址传给指针p,这样即把数组带入到函数中使用,在函数中
                   //可以改变数组的值,或者使用数组的值




六.strlen()和sizeof()对二维数组的用法的不同之处。




1. 数组名单独放在sizeof()内部,数组名表示整个数组sizeof(数组名)计算的是整个数组的大小,单位是字节


2. &数组名,数组名表示整个数组&数组名,取出的是整个数组的地址


3. 除此之外所有的数组名都表示首元素的地址
重点了解下面两个的输出结果:

//char arr[] = {'a','b','c','d','e','f'};


//printf("%d\n", strlen(&arr));//随机值  


//printf("%d\n", strlen(&arr+1));//随机值


虽然两个输出结果都是随机值,但是第二个比第一个值要正好小6
因为&arr的地址是整个数组的地址,那么&arr+1代表的是整个数组
的下一个储存单位的地址,也就是说&arr+1实际上是跳过了这个数组


4.补充一个知识点,如果
short s;
int a=1;
int b=1;
  printf("%d\n",sizeof(s=a+b));
上述输出的结果为 2
为什么呢?
因为编译器在执行程序时  先编译->链接->产生执行文件
表达式在执行文件.exe文件中才会执行,而sizeof()在编译的时候
就已经执行,也就是说sizeof()执行时只提取了s的类型short来进行
运算,这也就是为什么sizeof(int)这总写法也是合法的了。







例题:下列输出的结果是什么,如果下面的你都能算对,说明对数组的掌握还不错
1.
	//char arr[] = {'a','b','c','d','e','f'};
	//printf("%d\n", strlen(arr));//随机值
	//printf("%d\n", strlen(arr+0));//随机值
	printf("%d\n", strlen(*arr)); //err
	printf("%d\n", strlen(arr[1]));//err
	//printf("%d\n", strlen(&arr));//随机值
	//printf("%d\n", strlen(&arr+1));//随机值
	//printf("%d\n", strlen(&arr[0]+1));//随机值
// 	printf("%d\n", sizeof(arr));//7
// 	printf("%d\n", sizeof(arr+0));//4
// 	printf("%d\n", sizeof(*arr));//1
// 	printf("%d\n", sizeof(arr[1]));//1
// 	printf("%d\n", sizeof(&arr));//4
// 	printf("%d\n", sizeof(&arr+1));//4
//	printf("%d\n", sizeof(&arr[0]+1));




2.
	// 	printf("%d\n",sizeof(a));//16
// 	printf("%d\n",sizeof(a+0));//4
// 	printf("%d\n",sizeof(*a));//4
// 	//*a == *(a+0) == a[0];
// 	//arr[i] ==> *(arr+i)
// 	printf("%d\n",sizeof(a+1));//4
// 	printf("%d\n",sizeof(a[1]));//4
// 	printf("%d\n",sizeof(&a));  //4 
// 	printf("%d\n",sizeof(*&a)); //16
// 	printf("%d\n",sizeof(&a+1)); //4
// 	printf("%d\n",sizeof(&a[0]));//4
// 	printf("%d\n",sizeof(&a[0]+1));//4




3.
	//printf("%d\n", strlen(arr));//随机值
	//printf("%d\n", strlen(arr+0));//随机值
	printf("%d\n", strlen(*arr)); //err
	printf("%d\n", strlen(arr[1]));//err
	//printf("%d\n", strlen(&arr));//随机值
	//printf("%d\n", strlen(&arr+1));//随机值
	//printf("%d\n", strlen(&arr[0]+1));//随机值


// 	printf("%d\n", sizeof(arr));//6
// 	printf("%d\n", sizeof(arr+0));//4
// 	printf("%d\n", sizeof(*arr)); //1
// 	printf("%d\n", sizeof(arr[1]));//1
// 	printf("%d\n", sizeof(&arr));//4 
// 	printf("%d\n", sizeof(&arr+1));//4
// 	printf("%d\n", sizeof(&arr[0]+1));//4




4.
//char *p = "abcdef";
	//printf("%d\n", strlen(p));//6
	//printf("%d\n", strlen(p+1));//5
	printf("%d\n", strlen(*p));//err
	printf("%d\n", strlen(p[0]));//err
	//printf("%d\n", strlen(&p));//随机值
	//printf("%d\n", strlen(&p+1));//随机值
	//printf("%d\n", strlen(&p[0]+1));//5
	//int arr[3][4];
	//*(*(arr+1)+0)
	//*(*(arr)) = *(*(arr+0)+0)
	//	*arr = *(arr+0)
	//printf("%d\n", sizeof(p));//4
	//printf("%d\n", sizeof(p+1));//4
	//printf("%d\n", sizeof(*p));//1
	//printf("%d\n", sizeof(p[0]));//1
	//printf("%d\n", sizeof(&p));//4
	//printf("%d\n", sizeof(&p+1));//4
	//printf("%d\n", sizeof(&p[0]+1));//4



5.
	int a[3][4] = {0};
	//
	//int *p = a+1;
	short s = 1;
	int n = 10;
	printf("%d\n", sizeof(s=n+1));//2
	printf("%d\n", s);//
	printf("%d\n", sizeof(int));


	printf("%p\n", &a[0][0]);
	printf("%p\n", &a[0]+1);
	printf("%d\n",sizeof(a));//48 
	printf("%d\n",sizeof(a[0][0]));//4
	printf("%d\n",sizeof(a[0]));//16
	printf("%d\n",sizeof(a[0]+1));//4
	printf("%d\n",sizeof(a+1));//4
	printf("%d\n",sizeof(&a[0]+1));//4
	printf("%d\n",sizeof(*a));//16//sizeof(*(a+0))
	printf("%d\n",sizeof(a[3]));//





6.
	//int arr[3][4] = {0};


	//int *p = &arr[0][0];
	//int *p = &arr;
	//int(*p)[4];//
	//sizeof()
	//&arr


	//char arr[] = {'a','b','c','d','e','f'};


	//printf("%d\n", strlen(arr));//随机值
	//printf("%d\n", strlen(arr+0));//随机值
	printf("%d\n", strlen(*arr)); //err
	printf("%d\n", strlen(arr[1]));//err
	//printf("%d\n", strlen(&arr));//随机值
	//printf("%d\n", strlen(&arr+1));//随机值
	//printf("%d\n", strlen(&arr[0]+1));//随机值


// 	printf("%d\n", sizeof(arr));//6
// 	printf("%d\n", sizeof(arr+0));//4
// 	printf("%d\n", sizeof(*arr)); //1
// 	printf("%d\n", sizeof(arr[1]));//1
// 	printf("%d\n", sizeof(&arr));//4 
// 	printf("%d\n", sizeof(&arr+1));//4
// 	printf("%d\n", sizeof(&arr[0]+1));//4




7.
	//int a[] = {1,2,3,4};
	//printf("%p\n", &a[0]);
	//printf("%p\n", &a[0]+1);


	//printf("%p\n", a);
	//printf("%p\n", a+1);


	//printf("%p\n", &a);
	//printf("%p\n", &a+1);


总结   二维数组 int a[3][4]={0};
 在sizeof()中  a单独出现代表整个二维数组
&a代表整个二维数组的地址
a+0 代表二维数组的第一排的地址 
而 *(a+0)代表二维数组的第一排 ,a+0与*(a+0)的关系与 a与&a的关系类似

同时 *(a+0)等同于 a[0]

一维数组 int a[4]={0}中

在sizeof()里 a单独出现代表整个一维数组

a+0实际上代表一维数组中第一个元素的地址

*(a+0)代表第一个元素





  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值