一维数组与指针
- 格式:doc
- 大小:177.00 KB
- 文档页数:14
C语言数组参数与指针参数我们都知道参数分为形参和实参。
形参是指声明或定义函数时的参数,而实参是在调用函数时主调函数传递过来的实际值。
一、一维数组参数1、能否向函数传递一个数组?看例子:void fun(char a[10]){char c = a[3];}intmain(){char b[10] = “abcdefg”;fun(b[10]);return 0;}先看上面的调用,fun(b[10]);将b[10]这个数组传递到fun 函数。
但这样正确吗?b[10]是代表一个数组吗?显然不是,我们知道b[0]代表是数组的一个元素,那b[10]又何尝不是呢?只不过这里数组越界了,这个b[10]并不存在。
但在编译阶段,编译器并不会真正计算b[10]的地址并取值,所以在编译的时候编译器并不认为这样有错误。
虽然没有错误,但是编译器仍然给出了两个警告:warning C4047: 'function' : 'char *' differs in levels of indirection from 'char 'warning C4024: 'fun' : different types for formal and actual parameter 1这是什么意思呢?这两个警告告诉我们,函数参数需要的是一个char*类型的参数,而实际参数为char 类型,不匹配。
虽然编译器没有给出错误,但是这样运行肯定会有问题。
如图:这是一个内存异常,我们分析分析其原因。
其实这里至少有两个严重的错误。
第一:b[10]并不存在,在编译的时候由于没有去实际地址取值,所以没有出错,但是在运行时,将计算b[10]的实际地址,并且取值。
这时候发生越界错误。
第二:编译器的警告已经告诉我们编译器需要的是一个char*类型的参数,而传递过去的是一个char 类型的参数,这时候fun 函数会将传入的char 类型的数据当地址处理,同样会发生错误。
C语言中数组的总结目录1.数组的定义2.一维数组的创建和初始化3.给数组元素赋值4.数组下标越界5.二维数组6.多维数组7.指针与一维数组8.指针与多维数组9.指针,数组与函数10.变长数组11.以上全部内容数组的定义1.数组:一系列相同数据类型的有序序列。
2.声明数组:int states[50];char code[28];float candy[13]; 等等……通过声明将会告知编译器三个信息:1)数组内含有多少元素2)元素的数据类型3)数组名一维数组的创建和初始化1.数组的初始化:在数组创建时,我们要为数组初始化。
int months[12]={31,28,31,30,31,30,31,31,30,31,30,31};//数组的初始化int months[ ]={ 31,28,31,30,31,30,31,31,30};//初始化时省略方括号中的数字,编译器会根据初始化列表中项数来确定数组的大小。
(本例中数组的大小为9)const int months[12]={31,28,31,30,31,30,31,31,30,31,30,31};//将数组设置为只读,这样程序只能从数组中检索值,不能把新值写入数组。
(一旦声明为const,便不能再给他赋值)以花括号括起来,用逗号分隔数组元素来初始化数组,逗号和值之间可以使用空格。
C const 与C++ const区别一:c++允许在声明数组时使用const整数变量,而c不允许。
区别二:const定义的变量未初始化时,c会使用一个变量地址上的随机的值,c++会报错未初始化的const 'y'。
区别三:const int y;const int *p2 =&y;int * p1;p1 = p2;//c++不允许这么做(从'const int*'到'int*' [- fper]的无效转换),c 会给出一个警告(赋值从指针目标类型中丢弃“const”限定符)1)失败的初始化数组a)未初始化数组:数组元素和未初始化的普通变量一样,编译器使用的值是内存地址上现有的值,使得数组储存的都是垃圾值。
指针和一维数组经典题目
下面是一些经典的指针和一维数组题目:
1. 求一个一维数组的和、平均值、最大值、最小值。
2. 将一个一维数组元素逆序存放。
3. 合并两个有序的一维数组为一个新的有序数组。
4. 将一个一维数组中的奇数和偶数分别放在两个新的一维数组中。
5. 给定一个一维数组和一个目标值,判断目标值是否存在于数组中。
6. 给定一个一维数组和一个目标值,查找目标值在数组中的索引。
7. 统计一个一维数组中0的个数。
8. 对一个一维数组进行冒泡排序或选择排序。
9. 将一个一维数组循环右移k位。
10. 判断一个一维数组是否为回文数组。
这些题目可以帮助您巩固指针和一维数组的基本操作,同时也可以提高您的编程能力。
● 数组:数组是具有一定顺序关系的若干对象的集合体,组成数组的对象称为该数组的元素。
▲ 每个元素有n个下标的数组称为n维数组。
▲ a[100]:下标从0开始,到99止,不能为100。
▲ a[i][j]:i为行标,j为下标。
● 数组的声明:数组类型数组名[表达式1][表达式2]……● 数组的使用:数组类型数组名[表达式1][表达式2]……● 数组的存储:数组元素在内存中是顺序、连续存储的。
● 数组的初始化:就是在声明数组时给部分或全部元素赋初值。
▲ int a[3]={1,2,3}; 等价于 int[]{1,2,3};▲ int a[5]={1,2,3}; //部分初始化,必须连续,不能间隔赋初值▲ int a[2][3]={1,2,3,4,5,6}; 等价于 int a[][3]={1,2,3,4,5,6} //给出全部的初值时,行标可省▲ int a[2][3]={{1,2},{3,4},{5,6}};● 数组作为函数参数▲ 使用数组名传递数据时,传递的是地址▲ 使用数组名做函数的参数,则实参和形参都应该是数组名,且类型要相同▲ 对形参数组的修改,也就是对实参数组的修改▲ int ss(int a[][4],int bb) 调用:ss(b,x); //b是数组,x传递的是第一维的维数● 对象数组▲ 声明:类名数组名[下标表达式]▲ 引用:数组名[下标].成员名▲ 当一个数组中的元素对象被删除时,系统会调用析构函数来完成扫尾工作。
● 指针:是对地址直接操作的手段。
动态内存分配和管理也离不开指针● 指针类型:用来存放内存单元地址的变量类型,就是指针类型。
● 指针变量的声明:数据类型 *标识符;● 与地址相关的运算——"*"和"&"▲ "*"称为指针运算符(也称解析(dereference)),表示获取指针所指向的变量的值,是一元操作符。
c++函数数组参数传递C++中函数有多种参数传递方式,其中包括传递数组类型参数。
数组类型参数传递分为两种:传递一维数组和传递二维数组。
下面分别介绍这两种传递方式。
一、传递一维数组在C++中,一维数组的传递方式有两种:指针传递和数组引用传递。
指针传递是把数组名作为指针变量传递给函数,函数中可以通过指针进行数组元素的操作。
数组引用传递则是直接在函数的参数列表中声明数组类型变量,这样函数中就可以直接对数组进行操作,不需要通过指针间接操作数组元素。
1.指针传递对于一维数组的指针传递方式,函数在定义时需要使用指针类型作为形参,具体语法如下:```void func(int *arr, int len);```int *arr是指向int类型的指针变量,len表示数组的长度。
函数中可以通过下标和指针进行数组元素的操作。
例如:```void func(int *arr, int len){for(int i=0; i<len; i++){cout << arr[i] << " ";}cout << endl;}```在函数调用时,需要使用数组名作为实参传递给函数:sizeof(arr) / sizeof(arr[0])的结果就是数组的长度。
2.数组引用传递sizeof(arr) / sizeof(arr[0])的结果就是二维数组的行数,sizeof(arr[0]) / sizeof(arr[0][0])的结果就是二维数组的列数。
int (&arr)[3][3]表示arr是对一个3行3列的int类型数组的引用。
以上就是C++函数数组参数传递的全部内容,希望对大家有所帮助。
在实际开发中,我们经常需要在函数中传递数组类型参数,来完成各种数据处理操作。
此时,了解不同的数组传递方式,可以帮助我们更好地处理数据,提高程序效率。
值得注意的是,在C++中,数组名并不是指向数组首元素的指针,而是一个常量,它的值是一个地址,指向数组首元素。
指 针
1、 概述
1.1 地址和指针的概念
如果在C 语言中定义一个变量,系统会自动的给它存储空间。
比如:int a,b,c;系统会自动的给a,b,c 分别分配2个字节的空间,内存中的表示如下图:
这样以来,就建立了变量和地址的对应关系。
如果产生赋值行为,比如:a=1,b=3;,存储图如下:
如果产生具体的操作,比如:c=a+b ,具体的过程如下: 第一步:从2001-2002字节空间取出1; 第二步:从2003-2004字节空间中取出3;
第三步:将1和3相加后的结果4存入变量C 所指向的地址空间(2005-2006),图例如下:
a
b c
a
b c
以上的程序,在C 语言中称为“直接访问”。
既然有“直接访问”,肯定会存在“间接访问”,举例如下:
张三出差,住宾馆,房间号码为1001,从携带钥匙的方式上来看,有两种方式: 1、 钥匙自己带(直接方式);
2、 钥匙放在总台上,要开门,先到总台拿钥匙,而后开门(间接方式) 以上是生活中的例子,那么,在C 程序中,如何表示这种“间接方式”呢? 第一步:定义一个普通的变量并赋值(int a=3;)
第二步:定义一种变量,用来存储变量a 的地址(a_pointer );
第三步:建立该变量和普通变量之间的联系,将变量a 的地址存储到a_pointer 中。
第四步:通过该变量(a_pointer )来访问a;
程序如下:
b c
一种示意图:
以上的图形象的表示了一种“指向关系”。
“*”,表示指向。
在C 语言中,一个变量的地址被称为该变量的“指针”,存储该变量地址的“东东”,称为指针变量。
故,指针是一个地址,而指针变量是存放该地址的变量,它用来指向“指针”所表示的地址。
1.2 指针变量的定义和使用
定义格式:
数据类型(基本型) *指针变量
比如:int *pointer_1;指针变量是pointer_1,而不是*pointer_1; 有了以上的定义,pointer_1是我们定义的指针变量,*pointer_1是具体的内容。
从以上程序来看,*pointer_1和i 是一回事。
到此为止,我们已经知道了指针变量的定义,既然变量定义了,就要使用,如何使用呢?
要想使用,必须理解连个运算符号:
●&:取地址运算符
●*:指针运算(也称为“间接访问”运算符),取其指向的内容。
在指针定义和使用过程中的注意点:
通过以上的学习,我们的感觉:真烦!!!当时,随着学习的深入,我们会逐步体会到指针的好处:
●可以使程序简洁、紧凑、高效
●在函数调用后改变有关变量的值
●高效的处理数组和字符串
●动态分配内存
●直接处理地址
●有效的表示复杂的数据结构
●完成文件的操作
1.3 指针变量作为函数的参数
2、数组与指针
2.1 一维数组与指针
在前面的学习过程中,我们再三提到一个概念:数组名代表数组的首地址,比如: Int a[5]={12,34,56,78,11};
数组的数据在内存中的存储结构如下:
有了这张图以后,我们隆重推出一个重要的概念:a=&a[0]
如果我们定义了一个指针变量,并让其和数组a 建立联系,程序如下:
既然数组和指针建立了联系,该如何使用数组呢?
数组的使用,除了前面学过的使用下表法以外,只要数组和指针建立了联系,就可以通过指针的操作来使用数组。
a=&a[0]
a[0] a[1] a[2] a[3] a[4]
C语言规定:
●如果指针变量p指向数组中的一个元素,则p+1指向数组的下一个元素,p-1指向
数组的上一个元素。
●同理,根据p=a,则a+1指向数组的下一个元素,a-1指向数组的上一个元素。
下面,通过例子来说明:
例子:设有一个一维整形数组,有10个元素,请输出全部的原素。
【方法三】指针法:
在以上程序编写方法中:
1、下标法比较直观(大家喜欢);
2、以上三种方法中,方法三的执行效率最高,在方法三中,方法二执行效率最高。
3、注意p是变量,p++、p+=1都是成立的;a是常量,a++(--) 、a+=1是万万不行
的。
特别提醒各位的是,指针在“指来指去”的过程中,当前值是变化的。
对此,有可能造成程序的混乱。
例子:输入5个整数给整形数组,然后输出。
以上的程序看起来没有说明错误,但运行结果却是错的,为什么?
原因:经过第一个循环后,指针变量p中存储的已经不是&a[0]了,而是指向了数组的尾端,即p+5,其值不可预料,C在编译的时候不会提示错误,这对于初学者来说,很难发现,提醒大家注意。
2.2 一维数组作为函数的参数
以上的表,可以形成4种组合:
例子:编一个函数,求一数组中最小的元素。
【组合一】实参和形参均为数组名
实战训练
1、输入三个整数,按从大到小的顺序输出(用指针的方法)
2、通过指针操作,找出三个整数中的最小值并输出。
3、调用自定义的函数getint()读入以正整数,并将其输出(读程序,分析程序)。