0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

指数指针的相关知识

AGk5_ZLG_zhiyua 来源:未知 作者:佚名 2017-09-14 13:59 次阅读

周立功教授数年之心血之作《程序设计与数据结构》,书本内容公开后,在电子行业掀起一片学习热潮。经周立功教授授权,本公众号特对本书内容进行连载,愿共勉之。

第一章为程序设计基础,本文为1.8.3 指针数组。

>>>>1.字符串与指针数组

如果有以下定义:

int data0 = 1, data1 = 2, data2 = 3;

int *ptr0 = &data0, *ptr1 = &data1, *ptr2 = &data2;

实际上地址也是数据,那么数组也可以保存指针,因此可以在基本数据类型的基础上派生一个构造类型,即将相同类型的指针变量集合在一起有序地排列构成指针数组。在指针数组变量的每一个元素中存放一个地址,并用下标区分它们。虽然数组与指针数组存储的都是数据,但还是有细微的差别。数组存储的是相同类型的字符或数值,而指针数组存储的是相同类型的指针。比如:

int data0, data1, data2;

int *ptr[3] = {&data0, &data1, &data2};

该声明被解释为ptr是指向int的指针的数组(元素个数3),“int *[3]”类型名被解释为指向int的指针的数组(元素个数3)类型。即ptr指针数组是数组元素为3个指针的数组,其本质是数组,类型为int *[3],ptr[0]指向&data0,ptr[1]指向&data1,ptr[2]指向&data2。

由于ptr声明为指针数组,因此ptr[0]返回的是一个地址。当用*ptr[i]解引用指针(i=0~2)时,则得到这个地址的内容,即*ptr[0]==1,*ptr[1]==2,*ptr[2]==3。当然,也可以使用等价的指针表示法,ptr+i表示数组第i个元素的地址。如果要修改这个地址中的内容,可以使用*(ptr+i)。如果对**(ptr+i)解引用两次,则返回所分配的内存的位置,即可对其赋值。比如,ptr[1]位于地址&ptr[1],表达式ptr+1返回&ptr[1],用*(ptr+1)则得到指针&data1,再用**(ptr+i)解引用得到&data1的内容“1”。由此可见,使用指针的指针表示法,让我们知道正在处理的是指针数组。

显然,只要初始化一个指针数组变量保存各个字符串的首地址,即可引用多个字符串:

char * keyWord[5] = {"eagle", "cat", "and", "dog", "ball"};

其中,keyWord[0]的类型是char*,&keyWord[0]的类型是char **。虽然这些字符串看起来好像存储在keyWord指针数组变量中,但指针数组变量中实际上只存储了指针,每一个指针都指向其对应字符串的第一个字符。也就是说,第i个字符串的所有字符存储在存储器中的某个位置,指向它的指针存储在keyWord [i]中,即keyWord [0]指向“"eagle"”、keyWord [1]指向“"cat"”,keyWord[2]指向 "ant",keyWord[3]指向 "dog",keyWord[4]指向 "ball"。

尽管keyWord的大小是固定的,但它访问的字符串可以是任意长度,这种灵活性是C语言强大的数据构造能力的一个有力的证明。由于指针数组是元素为指针变量的数组,因此一个字符指针数组可以用于处理多个字符串。显然,将字符串制成一个表存放于指针数组的话,比使用switch语句效果更好。由此可见,数据的随机存储会以两种形式保存:存址和存值,存址方式详见图 1.14。一个数组包含了指向实际信息的指针,而不是直接将信息存储在数组元素的存储空间里。使用这种方式,可以灵活地存储和排序任何复杂结构的数据。

图 1.14 存址方式

相反地,基于值的存储将n个元素的数据集合打包存储在固定大小的记录块中,这个固定大小为s,存值方式详见图 1.15,每个字符串占用大小为6字节的连续存储块。

图 1.15 存值方式

为了便于说明多个字符串的引用,将设计一个数据交换函数。由于任何数据类型的指针都可以给void*指针赋值,因此可以利用这一特性,将void*指针作为byte_swap()函数的形参,即可接受任何类型数据。

由于C中最小长度的变量为char类型(包括unsigned char、signed char等),其sizeof(char)的结果为1,而其它任何变量的长度都是它的整数倍。比如,在32位系统中,sizeof(int)为4。由于C语言的变量类型多种多样,因此不可能为每一种变量类型编号,而且swap也并不关心变量的真正类型,所以可以用变量的长度代替变量类型。byte_swap函数原型为:

void byte_swap(void *pData1, void *pData2, size_t stSize);

其中,size_t是C语言标准库中预定义的类型,专门用于保存变量的大小。stSize为变量的长度,pData1、pData2分别为是要比较的第1、2个参数。当返回值< 0时,表示pData1 < pData2;当返回值= 0时,表示pData1 = pData2;当返回值> 0时,表示pData1 > pDta2。

在这里,任何类型的指针都可以传入byte_swap()中,真实地体现了内存操作函数的意义,无论这块内存是什么数据类型,它操作的对象仅仅是一块内存。无论用户传进来的是什么类型,从C99版本后,将void *类型指针赋值给其它类型指针时,不再需要强制类型转换。即循环一次交换一个字节,那么对于int类型数据来说,仅需循环4次就可以了。其前提是两个变量的类型必须相同,比如,交换a、b两个变量的值,其使用方法如下:

byte_swap(&a, &b, sizeof(a));

byte_swap()数据交换函数的接口与实现详见程序清单 1.42和程序清单 1.43。

程序清单1.42swap数据交换函数接口(swap.h)

1 #pragma once

2 void byte_swap(void *pData1, void *pData2, size_t stSize);

程序清单1.43swap数据交换函数接口的实现(swap.c)

1 void byte_swap(void *pData1, void *pData2, size_t stSize)

2 {

3 unsigned char *pcData1 = pData1;

4 unsigned char *pcData2 = pData2;

5 unsigned char ucTemp;

6

7 while (stSize--){

8 ucTemp = *pcData1; *pcData1 = *pcData2; *pcData2 = ucTemp;

9 pcData1++; pcData2++;

10 }

11 }

针对特定的字符串,指针数组的应用示例详见程序清单 1.44。

程序清单1.44比较字符串大小然后输出范例程序

1 #include

2 #include

3 #include "swap.h"

4

5 const char * keyWord[5] = {"eagle", "cat", "and", "dog", "ball"};

6 void show_str (void) //打印keyWord数据

7 {

8 for (int i = 0; i < sizeof(keyWord) / sizeof(keyWord[0]); i ++){

9 printf("%s", keyWord[i]);

10 }

11 printf("\n");

12 }

13

14 int main(int argc, char *argv[])

15 {

16 show_str();

17

18 if(strcmp(keyWord[0], keyWord[1]) < 0)

19 byte_swap(keyWord, keyWord +1, sizeof(keyWord[0]));

20 show_str();

21 return 0;

22 }

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 指针
    +关注

    关注

    1

    文章

    473

    浏览量

    70363

原文标题:周立功:你知道数组也能保存指针吗?

文章出处:【微信号:ZLG_zhiyuan,微信公众号:ZLG致远电子】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    C语言指针知识科普

    指针是C语言最重要也是最难理解的部分,它在我们平时的工作中无处不在。
    发表于 09-26 10:26 331次阅读

    经典著作《C和指针

    《C和指针》提供与C语言编程相关的全面资源和深入讨论。《C和指针》通过对指针的基础知识和高级特性的探讨,帮助程序员把
    发表于 11-26 10:17

    消毒柜相关知识

    消毒柜相关知识 为使大家进一步了解消毒柜基本知识,现简单介绍一些消毒柜相关知识。     基本术
    发表于 01-14 16:40 1216次阅读

    基础知识讲解:LED色温和显色指数的介绍

    要想了解LED照明,就必须了解LED色温。所以每个LED产品设计者都必须先接触LED色温的相关知识。LED色温的重要性足以影响产品的销售,只有符合标准的色温才能创造舒适的照明环境,本文介绍的就是LED色温和显色指数的基础
    发表于 11-05 08:03 8843次阅读

    C语言基础教程之指针知识点和使用总结

    指针是一种特殊的变量。它的特殊性表现在哪些地方呢?由于指针是一种变量,它就应该具有变量的三要素:名字、类型和值。于是指针的特殊性就应表现在这兰个要素上。指针的名字与一般变量的规定相同,
    发表于 11-13 17:55 6次下载
    C语言基础教程之<b class='flag-5'>指针</b>的<b class='flag-5'>知识</b>点和使用总结

    C和指针课后题答案完整版免费下载

    本书提供与C语言编程相关的全面资源和深入讨论。本书通过对指针的基础知识和高级特性的探讨,帮助程序员把指针的强大功能融入到自己的程序中去。
    发表于 11-13 08:47 0次下载

    理解函数指针、函数指针数组、函数指针数组的指针

    理解函数指针、函数指针数组、函数指针数组的指针
    的头像 发表于 06-29 15:38 1.4w次阅读
    理解函数<b class='flag-5'>指针</b>、函数<b class='flag-5'>指针</b>数组、函数<b class='flag-5'>指针</b>数组的<b class='flag-5'>指针</b>

    C和指针的电子书免费下载

    本书提供与C语言编程相关的全面资源和深入讨论。本书通过对指针的基础知识和高级特性的探讨,帮助程序员把指针的强大功能融入到自己的程序中去。
    发表于 03-22 16:06 98次下载

    043-ACMICPC相关知识

    043-ACMICPC相关知识(开关电源中高压电容怎么选择)-ACMICPC相关知识;ACMICPC相关
    发表于 07-26 11:56 12次下载
    043-ACMICPC<b class='flag-5'>相关</b><b class='flag-5'>知识</b>

    总降调度相关知识

    总降调度相关知识(开关电源技术与设计潘pdf)-总降调度相关知识                   
    发表于 09-23 16:33 8次下载
    总降调度<b class='flag-5'>相关</b><b class='flag-5'>知识</b>

    STM32位带引申的指针变量问题

    位带操作牵涉到的一个重要知识点就是指针变量。这种位带映射操作,就是操作映射过后的地址,其实就是操作指针变量(存放地址的变量)。
    发表于 02-08 15:57 3次下载
    STM32位带引申的<b class='flag-5'>指针</b>变量问题

    数组相关的双指针算法

    对于单链表来说,大部分技巧都属于快慢指针,前文 单链表的六大解题套路 都涵盖了,比如链表环判断,倒数第K个链表节点等问题,它们都是通过一个fast快指针和一个slow慢指针配合完成任务。
    的头像 发表于 04-28 16:22 1728次阅读

    C语言_字符串与指针的练习

    这篇文章涉及到字符串与指针知识点的相关练习。浮点数与字符串互转、字符串拷贝、字符串比较、指针交换变量、指针优先级、数据类型强制转换、内存拷贝
    的头像 发表于 08-14 09:51 1247次阅读

    C语言中指针及其相关知识

    数组在内存中只是数组元素的简单排列,没有开始和结束标志,在求数组的长度时不能使用指针p来sizeof(p) / sizeof(int)这样来求,因为 p 只是一个指向 int 类型的指针,编译器
    的头像 发表于 10-14 16:23 646次阅读

    晶体知识——晶向指数和晶面指数

    "在材料科学中讨论有关晶体的生长、变形、相变及性能等问题时,常需涉及晶体中原子的位置、原子列的方向(称为晶向)和原子构成的平面(称为晶面)。为了便于确定和区别晶体中不同方位的晶向和晶面,国际上通常用米勒指数(Miller indices)来统一标定晶向指数和晶面
    的头像 发表于 11-13 14:34 6563次阅读
    晶体<b class='flag-5'>知识</b>——晶向<b class='flag-5'>指数</b>和晶面<b class='flag-5'>指数</b>