文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

C语言指针和数组应用实例分析

2023-06-30 05:40

关注

这篇文章主要介绍“C语言指针和数组应用实例分析”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“C语言指针和数组应用实例分析”文章能帮助大家解决问题。

一、指针和数组分析-上

1.数组的本质

下面看一段代码:

#include <stdio.h> int main(){    int a[5] = {0};    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));        return 0;}

输出结果如下:

C语言指针和数组应用实例分析

通过这段代码说明指针运算是合法的。

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;}

输出结果如下:

C语言指针和数组应用实例分析

注意两个指针指向不同的数组,虽然它们两相减符合语法,但是最后的结果肯定没有意义。

再来看一段指针运算的应用代码:

#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;}

输出结果如下:

C语言指针和数组应用实例分析

注意以下几点:

3.指针的比较

4.小结

二、指针与数组分析-下 

1.数组的访问方式

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

C语言指针和数组应用实例分析

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

C语言指针和数组应用实例分析

2.下标形式 VS 指针形式

a[n] <--> *(a +n) <--> *(n + a) <--> n[a]

注意:现代编译器的生成代码优化率已大大提高,在固定增量时,下标形式的效率已经和指针形式相当;但从可读性和代码维护的角度来看,下标形式更优。

下面看一个数组的访问方式代码:

#include <stdio.h> int main(){    int a[5] = {0};    int* p = a;    int i = 0;        for(i=0; i<5; i++)    {        p[i] = i + 1;    }        for(i=0; i<5; i++)    {        printf("a[%d] = %d\n", i, *(a + i));    }        printf("\n");        for(i=0; i<5; i++)    {        i[a] = i + 10;    }        for(i=0; i<5; i++)    {        printf("p[%d] = %d\n", i, p[i]);    }        return 0;}

输出结果如下:

C语言指针和数组应用实例分析

注意这个奇怪的写法:i[a] = i + 10; ==> a[i] = i + 10;

下面通过一个实例,说明数组和指针的不同:

ext.c:

int a[] = {1, 2, 3, 4, 5};

test.c:

#include <stdio.h> int main(){    extern int a[];        printf("&a = %p\n", &a);    printf("a = %p\n", a);    printf("*a = %d\n", *a);     return 0;}

输出结果如下:

C语言指针和数组应用实例分析

下面来验证一下数组名究竟是不是指针,将 test.c 改成:

#include <stdio.h> int main(){    extern int* a;        printf("&a = %p\n", &a);    printf("a = %p\n", a);    printf("*a = %d\n", *a);     return 0;}

输出结果如下:

C语言指针和数组应用实例分析

ext.c 中 a[ ] 的地址为 0x804a014,test.c 中的extern int* a; 只是申明标识符 a,编译器会认为在这之前就已经给了地址值,就是 0x804a014,所以printf("a = %p\n", a); 就是打印0x804a014 地址中的 4 个字节的数,也就是 a[ ] 数组中的第一个元素 1,所以打印 0x1,*a 就是取 0x1 地址中的数,但是这个地址值是留给操作系统的,不可访问,访问就会产生段错误。

3.a 和 &a 的区别

C语言指针和数组应用实例分析

这个就能看出 a + 1 和 &a + 1 的不同,a + 1 增加的步长是一个元素的大小,&a + 1 则是增加的步长是整个数组的大小。

下面看一个指针运算的经典问题:

#include <stdio.h> int main(){    int a[5] = {1, 2, 3, 4, 5};    int* p1 = (int*)(&a + 1);     int* p2 = (int*)((int)a + 1);    int* p3 = (int*)(a + 1);        printf("%d, %d, %d\n", p1[-1], p2[0], p3[1]);        return 0;}

输出结果如下:

C语言指针和数组应用实例分析

p1[-1] 就是 *(p1 - 1),由于 p1 指向的元素是 5 后面的位置,减 1 之后就指向了 5;p2 的地址是 0x804a015(注意 linux 系统为小端系统),*p2 就是 0x02000000,对应十进制的值就是 33554432;p3 的地址为 &a[1],所以 p3[1] 就是 3 了。

C语言指针和数组应用实例分析

4.数组参数

数组作为函数参数时,编译器将其编译成对应的指针

C语言指针和数组应用实例分析

结论:一般情况下,当定义的函数中有数组参数时,需要定义另一个参数来标示数组的大小。

下面看一段代码:

#include <stdio.h> void func1(char a[5]){    printf("In func1: sizeof(a) = %d\n", sizeof(a));        *a = 'a';        a = NULL;} void func2(char b[]){    printf("In func2: sizeof(b) = %d\n", sizeof(b));        *b = 'b';        b = NULL;} int main(){    char array[10] = {0};        func1(array);        printf("array[0] = %c\n", array[0]);        func2(array);        printf("array[0] = %c\n", array[0]);        return 0;}

输出结果如下:

C语言指针和数组应用实例分析

这段代码就说明数组参数退化成指针,因为 sizeof(a) 为 4 个字节,而不是 5 个字节。

关于“C语言指针和数组应用实例分析”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注编程网行业资讯频道,小编每天都会为大家更新不同的知识点。

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     801人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     348人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     311人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     432人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     220人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯