c语言深度剖析(28)—指针和数组分析(上)

1. 数组的本质

  • 数组是一段连续的内存空间; 
  • 数组的空间大小为sizeof(array_type)*array_size; 
  • 数组名可看做指向数组第一个元素的指针常量。
  • 问题:
  • a + 1的意义是什么?结果是什么? 
  • 指针运算的意义是什么?结果是什么?
#include<stdio.h>

int main()
{
    int a[5] = {1, 2};
    int *p = NULL;

    printf("a = 0x%x\n", (unsigned int)(a));
    printf("a + 1 = 0x%x\n", (unsigned int)(a + 1));


    printf("p = 0x%x\n", (unsigned int)(p));
    printf("p + 1 = 0x%x\n", (unsigned int)(p + 1));

}
  • 运行结果:

     

  • %p是打印地址的,%x是以十六进制形式打印,完全不同!另外在64位下结果会不一样(%x在64位系统输出还是32位的)

2. 指针的运算

  • 指针是一种特殊的变量,与整数的运算规则为 : 
    • p + n; — (unsigned int)p + n * sizeof( *p ); 
  • 结论:当指针p指向—个同类型的数组的元素时: p+1 将指向当前元素的下—个元素;p -1将指向当前元素的上—个元素。 
  • 指针之间只支持减法运算 , 参与减法运算的指针类型必须相同,运算规则为 : p1 - p2;  — ( (unsigned int)p1 - (unsigned int)p2 )  /  sizeof(type); 
  • 注意: 
    • 只有当两个指针指向同—个数组中的元素时,指针相减才减有意义,其意义为指针所指元素的下标差 
    • 当两个指针指向的元素不在同一个数组中时,结果未定义 
  • 指针的比较
    • 指针也可以进行关系运算(<, <=,>,>=) 
    • 指针关系运算的前提是同时指向同—个数组中的元素 
    • 任意两个指针之间的比较运算(==,!=)无限制 
    • 参与比较运算的指针类型必须相同 
#include <stdio.h>

int main()
{
	char s1[] = { 'H', 'e', 'l', 'l', 'o' };
	int i = 0;
	char s2[] = { 'W', 'o', 'r', 'l', 'd' };
	char *p0 = s1;  // 指向数组第一个元素
	char *p1 = &s1[3];
	char *p2 = s2;
	int *p = &i;

	printf("%d\n", p0 - p1);
	//printf("%d\n", p0 + p2);  // error
	printf("%d\n", p0 - p2);    // 虽然编译通过,但结果不可预期
	printf("%d\n", p0 - p);  // error
	printf("%d\n", p0 * p2);  // error
	printf("%d\n", p0 / p2);  // error

	return 0;
}

3.编程实验

  • 指针运算的运用
#include <stdio.h>

#define DIM(a) (sizeof(a) / sizeof(*a))

int main()
{
	char s[] = { 'H', 'e', 'l', 'l', 'o' };
	char *pBegin = s;
	char *pEnd = s + DIM(s); // Key point
	char *p = NULL;

	printf("pBegin = %p\n", pBegin);
	printf("pEnd = %p\n", pEnd);

	printf("Size: %d\n", pEnd - pBegin);

	for (p = pBegin; p < pEnd; p++)
	{
		printf("%c", *p);
	}

	printf("\n");

	return 0;
}
  • 运行结果:

4.小结

  • 数组声明时,编译器自动分配一片连续的内存空间 
  • 指针声明时只分配了用于容纳地址值的4个字节空间(32位系统,64位占8个字节)
  • 指针和整数可以进行运算,其结果为指针,公式为:p+n; <==> (unsigned int)p + n * (sizeof( * p)) 
  • 当指针指向同一个数组时,指针之间支持减法运算,其结果为数组元素下标差
  • 指针之间支持比较运算,其类型必须相同
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值