专题4-3.数组与指针分析(国嵌C语言视频)

1. 数组本质

数组是一段连续的内存空间
数组的空间大小为sizeof(array_type) * array_size
数组名可看做指向数组第一个元素的常量指针

 

2. 指针的运算
指针是一种特殊的变量,与整数的运算规则为
p + n; (unsigned int)p + n*sizeof(*p);
结论:
当指针p指向一个同类型的数组的元素时:p+1将指向
当前元素的下一个元素;p-1将指向当前元素的上一
个元素。


指针之间只支持减法运算,且必须参与运算的指针类型必
须相同
p1 – p2; ( (unsigned int)p1 - (unsigned int)p2) / sizeof(type);
注意:
只有当两个指针指向同一个数组中的元素时,指针
相减才有意义,其意义为指针所指元素的下标差
当两个指针指向的元素不在同一个数组中时,结果
未定义

 

3. 指针的比较
指针也可以进行关系运算
< <= > >=
指针关系运算的前提是同时指向同一个数组中的元素
任意两个指针之间的比较运算(==, !=)无限制

4.

#include <stdio.h>
#include <malloc.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);
    printf("%d\n", p0 - p2);
    printf("%d\n", p0 - p);
    printf("%d\n", p0 * p2);
    printf("%d\n", p0 / p2);
	
    return 0;
}

#include <stdio.h>
#include <malloc.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);
    char* p = NULL;
	
    for(p=pBegin; p<pEnd; p++)
    {
        printf("%c", *p);
    }
    
    printf("\n");
    
    return 0;
}


5. 

数组的访问
以下标的形式访问数组中的元素
以指针的形式访问数组中的元素

下标VS 指针
从理论上而言,当指针以固定增量在数组中移动时,其效
率高于下标产生的代码
当指针增量为1且硬件具有硬件增量模型时,表现更佳
注意:
现代编译器的生成代码优化率已大大提高,在固定增
量时,下标形式的效率已经和指针形式相当;但从可
读性和代码维护的角度来看,下标形式更优。


   

#include <stdio.h>
#include <time.h>

int main()
{
    clock_t start;
    clock_t end;
    int a[10000];
    int b[10000];
    int* pEnd = &a[10000];
    int* pa = NULL;
    int* pb = NULL;
    int i = 0;
    int k = 0;
	
	start = clock();
	
    for(k=0; k<10000; k++)
	{
        for(i=0; i<10000; i++) 
        {
            b[i] = a[i];
        }
    }
    
    end = clock();
    
    printf("Index Timing: %d\n", end - start);
    
    start = clock();
    
    for(k=0; k<10000; k++)
	{
        for(pa=a, pb=b; pa<pEnd;)
        {
            *pb++ = *pa++;
        }
    }
    
    end = clock();
    
    printf("Pointer Timing: %d\n", end - start);
    
    return 0;
}



a和&a的区别
a为数组是数组首元素的地址
&a为整个数组的地址
a和&a的意义不同其区别在于指针运算
a + 1===>> (unsigned int)a + sizeof(*a)
&a + 1 ===>>(unsigned int)(&a) + sizeof(*&a)


 摩托罗拉的面试题.

int main(int argc, char *argv[])
{
    int a[5] = {1, 2, 3, 4, 5};
    int* p1 = (int*)(&a + 1);  //(unsigned int)(&a) + sizeof(*&a) ====>>p1 =&a[5];
    int* p2 = (int*)((int)a + 1);//a[5]这5个元素在内存空间的存放为 0x01 00 00 00 0x02 00 00 00  0x03 00 00 00 0x04 00 00 00 0x05 00 00 00
                                 //a+1 相当于,地址加1, 然后,下一个4个字节的地址的数据为 00 00 00 02,低位在前
                                 // 就是说下一地址所存的数据为0x02000000,然后把这个地址给到的p2,
    int* p3 = (int*)(a + 1); // (unsigned int)a + sizeof(*a) =====>>p3 =a[0+1];
    
    printf("%d\n %0x\n %d\n", p1[-1], p2[0], p3[1]);
    
    system("PAUSE");
    return EXIT_SUCCESS;
}


所示上面打印输出 5, 0x20000000 , 3


数组参数.

  
数组参数
C语言中,数组作为函数参数时,编译器将
其编译成对应的指针
void f(int a[]); void f(int* a);
void f(int a[5]); void f(int* a);
结论:
一般情况下,当定义的函数中有数组参数时,需要定
义另一个参数来标示数组的大小。

    正是因为这个灵活性,导致了C语言指针容易导致一些不容易查找的错误.

void f (int a[1000])
{
	printf ("%0d\n",sizeof(a));
}
int main(int argc, char *argv[])
{
    int a[5] = {1, 2, 3, 4, 5};
    f(a);
    printf ("%0d\n",sizeof(a));
    system("PAUSE");
    return EXIT_SUCCESS;
}


指针和数组的对比
数组声明时编译器自动分配一片连续内存空间
指针声明时只分配了用于容纳指针的4字节空间
在作为函数参数时,数组参数和指针参数等价
数组名在多数情况可以看做常量指针,其值不能改变
指针的本质是变量,保存的值被看做内存中的地址

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值