第4章 数组和指针的常用方法
来源:互联网 发布:it精英 编辑:程序博客网 时间:2024/05/29 19:11
4.1 基本使用方法
4.1.1 以函数返回值之外的方式来返回值
大型程序中,经常需要通过返回值返回程序处理的状态(比如是否成功,如果失败,还需要返回失败的原因)。
如果将指针作为参数传递给函数,此后在函数内部对指针指向的对象填充内容,就可以从函数返回多个值。
#include<stdio.h>void func(int *a,double *b) {*a=5;*b=3.5;} int main() {int a;double b;func(&a,&b);printf("a..%d b..%f\n",a,b);return 0;}将指向int和double的指针传递给函数,此后在函数内部对这两个指针指向的变量设定值。
要点:如果需要通过函数返回值以外的方式返回值,将”指向T的指针“作为参数传递给函数。
4.1.2 将数组作为函数的参数传递
C语言中,数组是不能作为参数进行传递的。但可以通过传递指向数组初始元素的指针,使得在函数内部操作数组称为可能。
#include<stdio.h>void func(int *array,int size) {int i;for(i=0;i<size;i++) {printf("array[%d]..%d\n",i,array[i]);}} int main() {int array[]={1,2,3,4,5};func(array,sizeof(array)/sizeof(int));return 0;}
要点:想要将类型T的数组作为参数进行传递,可以考虑传递”指向T的指针“。可是,作为被调用方是不知道数组的元素个数的,所以在必要条件下,需要使用其他方式进行参数传递。
4.1.3 可变长数组
通常C语言在编译时必须知道数组的元素个数,但也可以使用malloc()在运行时再为数组申请必要的内存区域。
这种数组称之为”可变长数组“。
#include<stdio.h>#include<stdlib.h>int main() {char buf[256];int size;int *variable_array;int i;printf("Input array size");fgets(buf,256,stdin);sscanf(buf,"%d",&size);variable_array=malloc(sizeof(int)*size);for(i=0;i<size;i++) {variable_array[i]=i;}for(i=0;i<size;i++) {printf("variable_array[%d]..%d\n",i,variable_array[i]);}return 0;}
必须注意,在使用malloc()实现可变长数组的时候,程序员必须自己来管理数组的元素个数。
要点:在需要获得类型T的可变长数组时,可以使用malloc()来动态地给”指向T的指针“分配内存区域。但此时需要程序员自己对数组的元素个数进行管理。
补充:Java中的数组只能使用内存堆区域。Java的数组和C中使用的malloc()分配的数组,有决定性的不同,Java的数组是知道自身的长度的。此外,尽管Java的数组是保存在堆中,但却不能改变长度,没有类似于realloc()的函数。
4.2 组合使用
4.2.1 可变长数组的数组 P166~P172
4.2.2 可变长数组的可变长数组 P172~P174
4.2.3 命令行参数
对于main()函数,标准中指出必须要写出以下两种方式之一:
int main(void);、int main(int argc,char *argv[]);
正常使用第一种形式,如果使用第二种形式,可以取得命令行参数。如在UNIX中的cat命令-用于输出文件的内容。 cat hoge.txt (命令名后是想要输出的文件名)
如果像cat hoge.txt piyo.txt 输出就是将hoge.txt 和piyo.txt两个文件的内容连接后所得的结果。
对于第二种形式,其实可以和下面这种形式是完全一样的。
int main(int argc,char **argv);
argv[0]保存了命令名自身。在程序输出错误提示信息时,或者需要通过命令名称改变程序的行为时,会经常使用arg[0]。
argc保存了参数的个数(包含了arg[0])。实际上,从ANSI C之后,会保证argv[argc]肯定为NULL,所以完全可以没有argc。
4.2.4 通过参数返回指针
要点:异常处理中使用goto,反而让程序更加简洁。
C++/java中具备异常处理机制的语言,可以不用goto、在C中也有setjmp()/longjmp(),使用它们也能达到相似的效果。
4.2.5 将多维数组作为函数的参数传递
#include<stdio.h>#include<stdlib.h>void func(int (*hoge)[3]) {int i,j;for(i=0;i<4;i++) {for(j=0;j<3;j++) {printf("%d ",hoge[i][j]);}putchar('\n');}}int main(void) {int hoge[][3]={{1,2,3},{4,5,6},{4,5,6},{7,8,9},{10,11,12},};func(hoge);return 0;}
4.2.6 数组的可变长数组
4.2.7 考虑使用结构体
补充:Java和C一样不存在多维数组,也是使用数组的数组来实现多维数组。但是Java和C不同的是,Java的数组都是指针,所以所谓的"数组的数组"其实是”指向数组的指针的数组“。
Java中的类(相当于C中的结构体)也是保存在堆中的,并且只能利用指针进行操作。因此Java中没有类似C中"结构体数组"这样对象。
阻碍Java程序快速执行的最大原因是Java过多使用了堆操作。
C++的对象可以不通过指针,而是通过实体来操作。为实现这个特性,C++使用了带参数的构造方法以及继承的概念,导致C++编程变得非常复杂。
4.3 违反标准的技巧
4.3.1 可变长结构体
4.3.2 从1开始的数组
C语言中,对指向超出数组范围以外的指针,除非它指向”最后元素的下一个元素“,其他情形都属于未定义。
补充:指针可以指到数组的最后元素的下一个元素。
for(p=&array[0];p<&array[SPAN];p++)这里没有使用循环计数器,而是使用指针遍历数组的各元素。当循环到达终点时,p指向&array[SPAN],也就是array的最后元素的下一个元素。
只是为了照顾以前写的代码,标准才允许指针可以指到数组的”最后元素的下一个元素“。
- 第4章 数组和指针的常用方法
- 【C++】指针和数组的常用方法
- 第4章 数组和指针
- 第4章 数组和指针
- 第4章:数组和指针
- 第4章 数组和指针
- 第4章 数组和指针
- 【C++ Primer】摘记--第4章 数组和指针
- 【C++Primer学习笔记】第4章 数组和指针
- 【C++ Primer】第4章 数组和指针
- 第4章 数组和指针 课后习题
- c++ primer 第4章 数组和指针
- 第5章 指针、数组和结构
- 指针(4):指针数组和数组指针的区别
- C语言程序现代设计方法---第12章:指针和数组
- c++ primer 第五版学习笔记-第6章-返回数组指针的函数和函数指针的数组
- [C++ Primer 第4版]第4章 数组和指针
- 数组常用的方法和案例
- POJ 3252 Round Numbers (数位dp)
- 【自动化测试】Jmeter的参数化及关联
- 10:超级玛丽游戏
- minSdk(API 21) > deviceSdk(API 19)解决
- Android简单病毒分析(样本名:百变气泡)
- 第4章 数组和指针的常用方法
- maven项目文件存在却找不到class
- TCP断点续传
- dom4j读取一个xml文件,以原格式输出
- spring-boot入门Demo
- javascript判断元素存在和判断元素存在于实时的dom中的方法
- [DP] POJ1050
- 关于vue 框架与后台框架的混合使用的尝试
- ios 多线程间通信