`

【转】《C专家编程》读书笔记(3)

阅读更多

 

原文地址:

http://blog.csdn.net/arthurkingios/archive/2007/05/11/1605110.aspx

***什么时候数组和指针是相同的***

 (1)“表达式中的数组名”就是指针;
对数组下标的引用总是可以写成“一个指向数组的起始地址的指针加上偏移量”。
例如,假如我们声明:

int a[10], *p, i = 2;

就可以通过以下任何一种方法来访问a[i]:

//第一种方法
= a;
p[i];
//第二种方法
= a;
*(p+i);
//第三种方法
= a+i;
*p;

编译器自动把下标值的步长调整到数组元素的大小。每个指针只能指向一种类型的原因所在:(1)编译器需要知道对指针进行解除引用操作时应该取几个字节;(2)每个下标的步长应取几个字节。

(2)把数组下标作为指针的偏移量
(3)“作为函数参数的数组名”等同于指针
“类型的数组”的形参的声明应该调整为“类型的指针”,编译器会将数组形式改写成指向数组第一个元素的指针形式。编译器只向函数传递数组的地址,而不是整个数组的拷贝。
下面三种形式通过编译器的隐式转换后是相同的:

void my_function(int* turnip) { ... }
void my_function(int turnip[]) { ... }
void my_function(int turnip[200]) { ... }

***数组与指针的其它知识点***

有一样操作只能在指针里进行而无法在数组中进行,那就是修改它的值。数组名是不可修改的左值,它的值是不能改变的。

func1(int* ptr)       func2(int arr[])     int array[100], array2[100];
{                          {                          main()
    ptr[
1= 3;             arr[1= 3;       {
    
*ptr = 3;               *arr = 3;               array[1= 3;
    ptr 
= array2;         arr = array2;        *array = 3;
}
                          }
                              array = array2;  //不能修改数组名
                                                       }

***C语言中的多维数组***

C语言中定义和引用多维数组唯一的方法就是使用数组的数组。像[i,j,k]这样的下标形式是C语言中的合法形式,只是它并非同时引用这几个下标(它实际所引用的下标值是k,即逗号表达式的值)。

访问多维数据carrot[10][20]中的单个字符都是通过carrot[i][j]的形式,编译器在编译时会把它解析为*(*(carrot+i)+j)的形式。

对多维数组中各层数组的访问:
int a[2][3][5];
int (*p)[3][5] = a;
int (*q)[5] = a[0];
int *r = a[0][0];

多维数组的初始化中一种有用的方法是建立指针数组。字符串常量可以用数组初始化值,例如:

char *vegetables[] = 
{
"carrot",
"celery",
"corn",
"cilantro"
}
;

多维数组中“数组的数组”和“字符串指针数组”的定位方式的差别:

(1)数组的数组:

char a[4][6];    //一个数组的数组
//在编译器符号表中,a的地址为9980
//运行时步骤1:取i的值,把它的长度调整为一行的宽度(这里是6),然后加到9980上
//运行时步骤2:取j的值,把它的长度调整为一个元素的宽度(这里是1),然后加到前面所得的结果上
//运行时步骤3:从地址(9980+i*scale_factor_1+j*scale_factor_2)
(2)字符串指针数组:
char *p[4];    //字符串指针数组
//在编译器符号表中,p的地址为4624
//运行时步骤1:取i的值,乘以指针的宽度(4个字节),并把结果加到4624上
//运行时步骤2:从地址(4624+i*4)取出内容,为“5081”
//运行时步骤3:取j的值,乘以元素的宽度(1个字节),并把结果加到5081上
//运行时步骤4:从地址(5080+j*1)取出内容

char *p[4]的定义表示p是一个包含4个元素的数组,每个元素为一个指向char的指针。查寻过程先找到数组的第i个元素(每个元素均为指针),取出指针的值,加上偏移量j,以此为地址,取出地址的内容。

“数组名被改写成一个指针参数”规则并不是递归定义的。数组的数组会被改写成“数组的指针”,而不是“指针的指针”。

实参                                                          所匹配的形式参数
数组的数组                 
char c[8][10];        char (*)[10];           数组指针
指针数组                     
char *c[15];           char **c;               指针的指针
数组指针(行指针) 
char (*c)[64];         char (*c)[64];        不改变
指针的指针                 
char **c;                char **c;              不改变

备注:数组指针是一个指向数组的指针,例如上图中的char (*c)[64]是一个指向64个元素的char数组的指针。

严格地说,无法直接从函数返回一个数组。但是,可以让函数返回一个指向任何数据结构的指针,当然也可以是一个指向数组的指针。
int (*f())[20]
{
int (*pear)[20];    //声明一个指向包含20个int元素的数组的指针
pear = (int(*)[20])calloc(20,sizeof(int));
return pear;
}

//调用该函数
int (*result)[20];
result 
= f();       //调用函数
(*result)[0= 1;   //访问结果数组
char a[4][6]的定义表示a是一个包含4个元素的数组,每个元素是一个char类型的数组(长度为6)。所以查找到数组中的第i个元素(前进i*6个字节),然后找到数组中的第j个元素。

 

分享到:
评论

相关推荐

    C专家编程读书笔记(上).pdf

    C专家编程读书笔记(上).pdf

    C 专家编程 适合有一定C基础的人看

    《C专家编程》是一本面向有一定C语言基础的读者的书籍,它的目标是帮助这些读者在C编程方面达到专家级别的水准。这本书由彼得·范·德·林登(Peter Van Der Linden)撰写,由徐波谋翻译,首次出版于2002年12月,由...

    谭浩强老师C语言程序设计PPT及笔记

    “谭浩强C程序设计和读书笔记以及PPT”这部分可能是谭浩强老师的个人授课笔记,其中可能包含了他对C语言更深层次的见解和独特的解题方法,也可能包括了课堂讲解的PPT,这些都为读者提供了丰富的学习材料。阅读这些...

    尚观培训linux许巍老师关于c语言的课程笔记和讲义

    【尚观培训Linux许巍老师关于C语言的课程笔记与讲义】是针对想学习或深化C语言理解的IT从业者及爱好者的一份宝贵资源。尚观是一家知名的IT培训机构,其提供的课程涵盖了广泛的IT领域,包括嵌入式Linux驱动开发。这份...

    《架构整洁之道》读书笔记.pdf

    《架构整洁之道》是软件开发领域的一本经典著作,由知名专家Robert C. Martin撰写。Martin先生不仅是cleancoders.com的联合创始人,还是Uncle Bob Consulting LLC的创始人,他在全球范围内提供软件开发咨询服务,...

    转嵌入式 Linux入门笔记

    这份"转嵌入式Linux入门笔记"提供了宝贵的资源,帮助初学者快速踏入这个领域。下面,我们将详细探讨嵌入式Linux的基本概念、重要性以及学习路径。 嵌入式Linux是指将Linux操作系统与硬件平台紧密结合,用于实现特定...

    python核心笔记pdf

    Python是一种高级、通用的编程语言,以其简洁明了的语法和强大的功能而受到广大程序员的...通过阅读这份笔记,读者不仅可以掌握Python的基本语法,还能了解到更高级的概念和技术,为成为Python开发专家打下坚实的基础。

    马士兵多线程训练营笔记

    在IT领域,多线程是并发编程中的一个关键概念,特别是在Java这样的多线程支持语言中。马士兵是一位知名的IT教育专家,他的多线程训练...在阅读和学习这些笔记时,结合实际的编程练习将有助于更好地理解和巩固所学知识。

    韦东山二期驱动笔记

    【韦东山二期驱动笔记】是一份针对Linux驱动程序开发的参考资料,由知名Linux技术专家韦东山编撰。这份笔记深入浅出地讲解了Linux内核驱动开发的基础与实践,旨在帮助读者理解和掌握Linux系统下的设备驱动编写技巧。...

    韩顺平笔记 PHP笔记 资料难得 赶紧下载吧

    此外,资料中的“3C3N导航-浓缩精华-双重搜索引擎.url”可能是提供其他学习资源的链接,帮助你在学习过程中找到更多相关的教程和问题解答。 总的来说,这份PHP笔记是一份宝贵的自学资料,它可以帮助你构建起完整的...

    C语言(谭浩强word版)和同步训练

    C语言是一种广泛应用于系统编程、应用编程、嵌入式开发等多个领域的高级编程语言,由Dennis Ritchie在20世纪70年代初为UNIX操作系统开发。它的语法简洁、灵活,且对硬件的控制能力强,因此深受程序员喜爱。谭浩强...

    ARM嵌入式系统技术笔记-基于LPC2300上

    在软件开发方面,读者可以学习到C语言编程技巧,特别是在嵌入式环境下的优化方法。同时,了解如何使用开发工具,如Keil uVision或者GCC编译器,进行项目配置、编译、链接以及调试。这有助于读者将理论知识转化为实践...

    精读特训笔记.zip

    本压缩包“精读特训笔记.zip”包含了关于精读学习方法和技巧的详细资料,旨在帮助用户提升阅读理解能力,尤其是对于专业文章和技术文档的理解。精读是一种深入理解文本的阅读策略,它要求读者不仅理解文字表面意思,...

    开发专家 Visual C 开发入行真功夫光盘

    标题中的“开发专家 Visual C 开发入行真功夫光盘”表明这是一份与Visual C++编程相关的学习资源,可能是包含教程、实例代码、练习题等的光盘内容。Visual C++是微软公司开发的一款集成开发环境(IDE),主要用于...

    C语言学习课件(北邮版)

    这个课件可能包含了一系列的讲座笔记、课后练习、实例代码和解题思路,由北京邮电大学的专家精心编撰。北京邮电大学作为中国知名的高等学府,其计算机科学教育具有较高的权威性,因此,这个课件的质量可以得到保证。...

    一步一步学VB2005数据库编程

    "WROX-Expert_One_On_One_Visual_Basic_2005_Database_Programmingc.pdf"看起来是一本完整的电子书,由著名的技术出版商Wrox出版,专门探讨VB2005的数据库编程,包含专家级别的指导和实践案例。"E书说明.txt"可能是...

    STM32自学笔记 2012.rar

    STM32是一款基于ARM ...通过阅读《STM32自学笔记》,读者将能全面了解STM32的基本概念、开发流程和实战技巧,为成为STM32领域的专家奠定坚实基础。同时,结合实际项目练习,能够更好地巩固理论知识,提高动手能力。

    FPGA学习笔记 FPGA

    FPGA(Field-Programmable Gate Array)是一种可编程逻辑器件,允许用户根据需求自定义数字电路。在本文中,我们将探讨FPGA的学习路径、主要工具以及相关资源,旨在为初学者提供指导。 首先,学习FPGA需要掌握硬件...

    oracle笔记 (PL-SQL)

    Oracle笔记(PL-SQL)是关于数据库管理和编程的一个重要主题,主要聚焦于Oracle数据库系统中的结构化查询语言(SQL)的扩展——PL/SQL。PL/SQL是一种过程化语言,结合了SQL的功能,使得开发者能够编写复杂的数据库应用...

Global site tag (gtag.js) - Google Analytics