【C语言补漏】 指针和数组区别

先来一个例子:计算字符串的长度

#include<stdio.h>

#define MAX 1024

void main()
{
	char str[1024];
	char *target = str;
	int length = 0;

	printf("请输入一个字符串:");
	fgets(str, MAX, stdin);//从指定文件中读取字符串

	while (*target++ != '\0') //自增运算符(++)的优先级比取值运算符(*)要高,
	{
		length++;
	}

	printf("您一共输入了%d个字符\n", length-1);

}

其中:

while (*target++ != '\0')

是不能用 “while (*str++ != '\0')” 代替的,应为自增运算符需要的是左值,也就是说能被修改的值,但是显然数组的名字是不能被修改的!

这就是数组和指针两者的区别之一!

指针数组和数组指针

先区分下:指针数组是数组,数组指针是指针。

指针数组 

int *p1[5]

上面的定义中,有取值运算符“*”和下表运算符“[5]”,根据优先级的关系,下表运算符“[5]”运算级别高。所以是一个数组。

所以,这是一个指向整型变量的指针。

结论:指针数组是一个数组,每一个数组元素存放一个指针变量。

先看一个例子:

#include<stdio.h>

void main()
{
	int a = 1;
	int b = 2;
	int c = 3;
	int d = 4;
	int e = 5;

	int *p[5] = {&a,&b,&c,&d,&e};
	printf("&a = %p\n", &a);//变量a的地址	
	printf("*p = %p\n", *p);//指针数组的第一个元素:变量a的地址
	printf("p[0] = %p\n", p[0]); //指针数组的第一个元素:变量a的地址,相当于*p
	printf("*p[0] = %d\n", *p[0]);//变量a
}

运行结果:

&a = 0000004560F4F4C4
*p = 0000004560F4F4C4
p[0] = 0000004560F4F4C4
*p[0] = 1
请按任意键继续. . .

数组指针

int (*P2)[5]

看下图示意

结论:数组指针是一个指针,它指向的是一个数组

看下面的程序

#include<stdio.h>

void main()
{
	int temp[5] = { 1,2,3,4,5 };
	int *p = temp;//p是指向第一个数组元素的指针,也可以说是指向整型变量的指针,不是一个数组指针,
	int(*p2)[5] = &temp;//这才是一个正儿八经的数组指针,这里要的是整个数字的地址
	int i;
	printf("---------(1)--------\n");
	for (i = 0; i < 5; i++)
		printf("%d\n", *(p + i));
	printf("--------(2)---------\n");
	for (i = 0; i < 5; i++)
		printf("%p\n", (*p2 + i));
	
	printf("---------(3)--------\n");
	for (i = 0; i < 5; i++)
		printf("%p\n", (&temp[i]));

	printf("---------(4)---------\n");
	for (i = 0; i < 5; i++)
		printf("%d\n", *(*p2 + i));

	printf("---------(5)---------\n");
	for (i = 0; i < 5; i++)
		printf("%d\n", *(&temp[i]));
}

运行结果:

1
2
3
4
5
--------(2)---------
0000007961D3F548
0000007961D3F54C
0000007961D3F550
0000007961D3F554
0000007961D3F558
---------(3)--------
0000007961D3F548
0000007961D3F54C
0000007961D3F550
0000007961D3F554
0000007961D3F558
---------(4)---------
1
2
3
4
5
---------(5)---------
1
2
3
4
5
请按任意键继续. . .

检测题

0. 请问 str[3] 和 *(str + 3) 是否完全等价?

答:完全等价。在c语言中,数组名是被作为指针来处理的。更确切的说,数组名就是指向数组的第一个元素的指针,而数组的索引下标就是距离第一元素的偏移量,这也解释了为了在C语言中下标是从0开始的,因为这样它的索引可以对应到偏移量上。因此,str[3] 和 *(str + 3) 是完全等价的,在内部,编译器都会江他们解释为 *(str+3)。

1. 请问下边代码是否可以正常执行?如果可以,会打印什么值?如果不行,请说明原因?

#include <stdio.h>

int main()
{
        int a[5] = {1, 2, 3, 4, 5};
        int *b;

        b = &a[3];
        printf("%d\n", b[-2]);

        return 0;
}

答:可以正常执行。

解析:由于数组的下标法跟指针法访问时等价的,所以b[-2]相当于*(b-2)。就是a[1] = 2 

2. 为什么不能使用 if (str1 == str2) 这样的形式来比较两个字符串?

答:因为这样比较的是两个字符串的指针,而不是字符串本身

3. 如果数组 array 的定义如下

int array[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};

请问 array 和 &array 有区别吗?

答:有区别。

解析:虽然array和&array的值相同,但是含义是不一样的。array表示数组第一个元素的位置,而&array表示的是整个数组的位置(这里是将array看做是一个整体来看待的)


★finished by songpl.2018.12.28

猜你喜欢

转载自blog.csdn.net/plSong_CSDN/article/details/85326989