c语言学习笔记数组函数.docx
- 文档编号:7461760
- 上传时间:2023-01-24
- 格式:DOCX
- 页数:33
- 大小:26.11KB
c语言学习笔记数组函数.docx
《c语言学习笔记数组函数.docx》由会员分享,可在线阅读,更多相关《c语言学习笔记数组函数.docx(33页珍藏版)》请在冰豆网上搜索。
c语言学习笔记数组函数
数组
2010-3-2922:
40
一维数组的定义和一维数组的引用
内存中一串连续的存储单元(变量),叫数组。
指针移动和比较只有在一串连续的数组中才有意义。
当数组中每个变量只带一个下标时,为一维数组。
定义一个一维数组:
类型名数组名【常量表达式】如:
inta[8];
说明:
①定义一个一维整型名为a的数组。
②方括号中规定此数组有8个元素,(a【0】-a【7】),不存在a【8】这个元素。
③a数组中每个元素均为整型,且每个元素只能存放整型。
④每个元素只有一个下标,且第一个元素的下标总为0。
⑤c编译程序,为a数组开辟8个连续存储单元。
3)在定义数组语句中,可以有多个数组说明符;它们用逗号隔开。
例:
doublea【22】,v【100】,u【5】,a,b,c;注:
双精度型每个单元占用8个字节的存储空间。
另外,也可以和普通变量一起定义。
用逗号分隔开。
2010-3-2310:
29
一维数组元素的引用2
1)
引用形式:
数组名【下标表达式】可以是:
常量,变量,表达式。
如:
doublex【8】则x【0】x【j】x【i+k】均合法
2)
(1)一个数组元素实际上就是一个变量名,代表内存中的一个存储单元。
我们可以把数组元素看做一个变量名来处理。
(2)一个数组不能整体引用,数组名中存放的是一个地址常量,它代表整个数组的首地址。
当学习指针时,引用的变量的地址,就是变量中第一个字节的地址。
数组的首地址也是它的第一个元素的第一个字节的地址,即它的首地址。
数组的首地址存放在数组名中。
所以说,数组名就代表一个地址。
数组名是一个地址值。
(3)在引用数组元素时,数组元素下标表达式必须是整数,下标表达式下限为0.系统并不自动检验数组元素下标是否越界,因此编程时要注意。
如:
doublea,b;intc[10];
a=2.0;b=3.0;
则a[i];是不合法的。
给数组赋初值时,如果所赋初值少于元素个数时,后面的元素补为0,字符补为’\0’
可以通过赋初值来定义一个数组的大小。
如:
inta[]={0,0,0,0,0};相当于:
a[5]={0};
一维数组的初始化
voidmain()
{
inti,j,a[30];
for(i=0,j=1;i<30;i++,j+=2)
a[i]=j;
for(i=0;i<30;i++)
{
if(i%10==0)printf(“\n”);/*i等于10,到了十,输入回车。
因为0-9就是十个*/
printf(“%d,”,a[i]);
}
for(i=29;i>=0;i--)
{
printf(“%d,”,a[i]);
if(i%10==0)printf(“\n”);/*先输出第i=20这个元素,再输入回车。
*/
}
getch();
}//2010年10月14日14:
43:
15上次是怎么做的啊,错了那么多。
1一维数组和数组元素的地址
1)数组和指针的比较
(1)指针变量的地址:
指向内存中一个存储单元的第一个字节的地址。
数组名的地址值,就是该数组的第一个元素的第一个字节的地址。
(2)指针变量有基类型,相当于数组的类型名。
(3)指针变量的地址值不可改变,即指针变量指向的存储单元的地址值是固定的,不可改变,如int*p,a;p=&a;则变量a的地址是不可改变的。
也不可给数组名的地址重新赋值。
如数组名为a的数组:
a=&x;或a++等给数组名重新赋值都是错误的。
一旦定义,a永远指向a数组的首地址。
(4)虽然不可改变a的内容(地址),但可以对数组名加一个整数的办法,来依次表达该数组中不同元素的地址。
如:
a代表&a【0】数组的首地址,也是a[0]的地址//首地址
a+1代表&a【1】数组元素a[1]的地址//在指针中,1代表一个存储单元
a+2代表&a【2】......//注意:
不是a=a+1,而是a+1
例:
main()
{
inta[10],*p,x,k;
for(k=0;k<10;k++)p=a+k;//a是数组的首地址,p=a+k;则遍历了数组中每个元素
for(k=0;k<10;k++)scanf("%d",a+k);//输入每个元素的值
for(k=0;k<10;k++)printf("%d\n",a[k]);//打印每个元素的值
getch();
}
p=&a[0];等价于p=a;
以下语句等价:
for(p=a,k=0;k<10;k++)p++;//将数组a的首地址赋给指针p,k从0到9,p++将遍历数组中每个元素的地址。
依次指向数组a1,a2,a3......a9.
for(p=a,k=0;k<10;k++){scanf("%d",p);p++;}
for(p=a,k=0;k<10;k++)scanf("%d",p++);//什么自加自减运算符,当++在后面时,当前表达式的值不变,元素加1.
for(p=a;p-a<10;p++)scanf(“%d”,p);
2010.4.2
通过数组首地址指针带下标的指针引用一维数组元素。
引用一维数组中的某一个元素的方法:
*:
求当前地址的内容&:
求当前内容的地址
1a【i】
2*&a【i】//*在定义语句时代表定义一个指针变量,当在执行语句部分时代表间址运算符,引用一个指针变量指向的地址的内容。
&叫求地址运算符,求当前内容的地址。
所以*和&就像乘号和除号一样,互相抵消了。
3*(a+i):
在数组名的地址上,加上i个存储单元。
代表第(i+1)个元素,用间址运算符引用它,即等价于a[i]
4当(p=a;||p=&a【0】)则*(p+i)等价于a[i]
5当(p=a;||p=&a[0])则p[i]等价于a[i]//方括号不仅表示数组元素的记号,也是一种运算符.
总结:
引用一维数组元素a[i]的四种方法:
a[i]*(a+i)若p=a,则p[i]*(p+i)
表示a[i]的地址的方法:
&a[i]a+ip+i都表示当前数组第i个元素的地址。
以下代表什么:
*(P--)a[i--]*--pa[--i]
注:
自加自减运算,p--等价于:
m=p--m=pp=p-1//先赋值,(先取值)再改变
--p等价于:
m=--pp=p-1m=p//先改变,再赋值。
(再取值)
数组名a和指向数组的指针p的区别.前者不可变,不可运算,后者可以赋值,运算.
a++是个赋值表达式
3)逐个输出a数组中元素的值.
for(k=0;k<10;k++)printf("%4d",*(a+k));
for(k=0;k<10;k++)printf("%4d",a[k]);
for(p=a,k=0;k<10;k++)printf("%4d",*(p+k));
for(p=a,k=0;k<10;k++)printf("%4d",p[k]);
for(p=a,k=0;k<10;k++){printf("%4d",*p);p++}//p++,即依次指向每一个元素。
函数之间对一维数组和数组元素的引用及一维数组实例1
1数组元素作为实参
在调用函数时,数组元素可以作为实参传送给形参,每个数组元素实际上代表内存中的一个存储单元和普通变量一样,对应的形参必须是类型相同的变量。
2数组名作实参
如果用数组元素作实参的话,数组元素的值,可以传送给形参中相同类型的一个变量,在函数中只能对该变量进行操作,而不能直接引用对应的数组元素。
(只能改变形参的值,而不能改变实参即数组元素的值)。
数组名也可以作为实参传送,对应的形参就应该是一个指针变量来引用调用函数中对应的数组元素,从而达到对调用函数中对应数组元素进行操作的目的。
但数组名本身是一个地址值,因此,对应的形参就应当是一个指针变量。
(该指针变量指向主调函数中数组的首地址)该指针变量就可以来引用主调函数中对应的任何一个数组元素,从而达到对主调函数中对应的数组元素进行操作的目的。
引用方法:
a【i】;*(a+i);p【i】;*(p+i)
例:
编写程序,通过函数给数组输入若干大于等于0的整数,用负数作为输入结束的标志;调用函数输出该数组中的数据。
#defineM100
intarrin(int*a)
{
inti=0;
scanf("%d",&a[i]);
while(a[i]>=0)
{
i++;
scanf("%d",&a[i]);
}
returni;
}
arrout(int*a,intn)
{
inti;
for(i=0;i { printf("%d,",a[i]); } } main() { inta[M],n; n=arrin(a); arrout(a,n); getch(); } 2010年10月16日8: 46: 45自己做的(修改后) #defineM100 intmain(void) { inta[M],n; n=input(a); output(a,n); getch(); } intinput(int*a) { inti=0; scanf("%d",a+i); while(*(a+i)>=0) { i++; scanf("%d",a+i); } returni; } intoutput(int*a,intn) { inti; for(i=0;i { printf("%d,",a[i]); } } 上例中,在数组只输出正数,作为结束标志的负数不输出。 #defineM10 intmain(void) { inta[M]={0}; input(a); output(a); getch(); } intinput(int*a) { inti=0; scanf("%d",a+i); while(*(a+i)>=0) { i++; scanf("%d",a+i); if(a[i]<0){a[i]=0;break;}/*作为结束标志的负数赋值为0然后结束*/? 还是有很多问题啊。 } } intoutput(int*a) { inti; for(i=0;i { printf("%d,",a[i]); } } 当实参为数组名时,形参可以有3种表示方法: 1指针2一个数组的形式3直接用数组名。 (三者形式不同,但其实质还是一个指针) a(int*a)a(inta[])a(inta[M]) *(a+i)等价于a[i]都表示数组中的第i个元素 上面形参中数组a[]或a[M],都指向实参中数组首地址,它们只是与实参数组形式上相似,但在被调用函数中并未为形参开辟一串存储单元,它们本质还是指针。 只是用数组的形式引用而已。 函数之间对一维数组和一维数组的元素的引用及一维数组实例2 当数组元素地址作为实参时,因为是地址值,所以对应的形参也应当是基类型相同的指针变量,或数组名加空括号,或数组。 例题: 编写函数,对具有10个元素的char类型数组,从下标为4的元素开始,全部设置‘*’,保持前四个元素内容不变。 fun(char*a,intn) { inti; for(i=0;i { *(a+i)='*'; } } arrout(char*a,intn) { inti; for(i=0;i { printf("%c",a[i]); } } main() { chara[10]={'a','b','c','d','e','f','g','h','i','j'}; fun(&a[4],6); arrout(a,10); getch(); } 2010年10月18日0: 20: 09自己重做的。 charcharb(char*); intmain() { inti; chara[10]={'a','b','c','d','e','f','g','h','i','j'}; for(i=0;i<10;i++) { printf("%c,",a[i]); } printf("\n"); charb(a); for(i=0;i<10;i++) { printf("%c,",a[i]); } getch(); } charcharb(char*ch) { inti; for(i=4;i<10;i++) { ch[i]='*'; } } 2010年10月18日0: 23: 51参考金文老师的程序后,又修改的。 charcharb(char*); voidarrout(int,int,char*a); intmain() { inti; chara[10]={'a','b','c','d','e','f','g','h','i','j'}; arrout(0,10,a); printf("\n"); charb(a); arrout(0,10,a); getch(); } voidarrout(intx,inty,char*a) { inti; for(i=x;i { printf("%c,",a[i]); } } charcharb(char*ch) { inti; for(i=4;i<10;i++) { ch[i]='*'; } }//把相同功能的模块,比如,输出做成一个函数。 ……此程序不是用数组元素地址做实参,而是用数组名作实参。 (程序功能的实现有多种方法。 ) 数组名作实参时对应的形参: a*aa[]a[10] 数组元素的地址做实参时对应的形参: &a[4]*aa[]a[6]? 还要再理解 函数之间对一维数组和一维数组的元素的引用及一维数组实例3 4函数的指针形参以及在在函数体中定义的数组和主调函数体中数组的区别 例: 以下程序,形参a指向w数组,被调函数体内定义了一个数组b,被调函数把b数组的起始地址作为函数值返回,企图使指针p指向函数体内b 数组的开头。 #defineN10//定义符号常量,10 int*fun(inta[N],intn) { intb[N]; ...... returnb; } main() { intw[N],*p; ...... p=fun(w,N); ...... } //任何函数,在被调用执行后,为其开辟的存储单元就会被释放掉。 试图返回一个已经被释放掉的数组的首地址,是没有结果的。 注: 1)函数fun中,形参a可以写成三种形式: a[N],a[],*a;它是一个指针变量,在调用fun函数时,系统只为形参a开辟一个存储单元,并把main函数中w数组首地址存进去,使它指向w数组地址。 2)函数fun的函数体定义了一个b数组,在调用fun函数时,系统为它开辟了一串连续存储单元,它是一个地址常量。 ? 3)在fun函数执行完毕后,系统释放a和b所占存储单元,而b的值作为fun函数返回值,指针p将不指向任何对象而成为“无向指针” 。 函数之间对一维数组和一维数组的元素的引用及一维数组实例4 2010年10月18日21: 49: 53又从互联网上学了一招: a%=4-1等价于a=a%(4-1)即a=a%3即a=2 1编写程序,定义一个含有15个元素的数组,并编写数组分别完成以下操作。 1)调用库函数中的随机函数给所有元素赋以0-50之间的随机数; 2)输出数组元素中的值 3)按顺序对每隔三个数求一个和数,并传回主函数 4)最后输出所有求出的和值。 #include"stdlib.h" #include"stdio.h" getrand(int*a,intn) { inti; for(i=0;i { a[i]=random(50); } } arrout(int*a,inn) { inti; for(i=0;i { printf("%d\n",a[i]); } } getsum(int*a,int*b,intn) { inti,j,sum; for(i=0,j=0,sum=0;i { sum+=a[i]; if((i+1)%3==0) { b[j]=sum; sum=0; j++; } } } main() { inta[15],w[5]={0}; getrand(a,15); arrout(a,15); getsum(a,w,15); arrout(w,5); getch(); }//为什么每次运行都是一样的结果? 注: 随机函数前要加随机数种子函数randomize(); #include main() { inti,a,b,h,sum=0; for(i=0;i<10;i++) { randomize();//随机数种子初始化函数 a=random(5); b=random(5); sum=a+b; printf("%d+%d=",a,b); scanf("%d",&h); while(sum! =h) { printf("cuole\n"); printf("%d+%d=",a,b); scanf("%d",&h); } printf("duile\n"); } getch(); } 2010年10月19日12: 32: 46自己做的,和金文老师的程序很不同,但也完成了题目要求的功能,到底哪个更好一些呢? #include"stdio.h" intmain() { inti,j,a[15],b[5],k=0; srand((unsigned)time(NULL));//采用时间作为随机种子 for(i=0;i<15;i++) { a[i]=rand()%51;//(y-x+1)+x取x-y之间的随机数公式。 } arrout(a,15); printf("\n"); for(j=0;j<15;j+=3) { b[k]=sanshuhe(a[j],a[j+1],a[j+2]); k++; } arrout(b,5); getch(); } intarrout(int*a,intn) { inti; for(i=0;i { if(i%3==0)printf(""); printf("%d,",*(a+i)); } } intsanshuhe(inta,intb,intc) { intsum; sum=a+b+c; returnsum; } 函数之间对一维数组和一维数组的元素的引用及一维数组实例5 经典程序: 将数组中的数按颠倒的顺序重新存放。 在操纵时,只能借助一个临时存储单元而不得另外开辟数组。 arrout(int*x,intn) { inti; for(i=0;i { printf("%d",x[i]); } printf("\n"); } fun(int*x,int*y,intn) { inti,j=n-1; for(i=0;i { y[j]=x[i]; j--; } } main() { inta[5]={1,2,3,4,5},b[5]={0}; arrout(a,5); fun(a,b,5); arrout(b,5); getch(); }//why? ? ? 第二天晚上,搞定了! 正确解法: arrout(int*a,intn) { inti; for(i=0;i { printf("%d",a[i]); } printf("\n"); } fun(int*a,intn) { inti,j,t; i=0;j=n-1; while(i { t=a[i];a[i]=a[j];a[j]=t; i++; j--; }//这个算法很好啊。 运算才6次。 看来一个程序的算法真是很重要啊,差别太大了。 } main() { inta[5]={1,2,3,4,5}; arrout(a,5); fun(a,5); arrout(a,5); getch(); } 2010年10月19日15: 40: 27自己做的。 intmain() { intt,i,j,a[5]={1,2,3,4,5}; arrout(a); for(i=4;i>0;i--) { for(j=0;j { t=a[j];a[j]=a[j+1];a[j+1]=t;//不过此算法并不好,运算达到46次。 } } arrout(a); getch(); } intarrout(int*a) { inti; for(i=0;i<5;i++) { printf("%d,",*(a+i)); } printf("\n"); } 函数之间对一维数组和一维数组的元素的引用及一维数组实例620104.9 已知数组中的值在0-9的范围内,统计每个整数的个数。 #include getdate(int*a,intn) { inti; for(i=0;i { a[i]=random(10); } } outdate(int*a,intn) { inti; for(i=0;i { printf("%d,",a[i]); } printf("\n"); } fun(int*a,int*b,intn) { inti; for(i=0;i { b[a[i]]++;//此算法不错,须记住! 金文老师说: 这也是一道经典程序,必须记下来。 } } main() { inta[50],b[10]={0}; getdate(a,50); outdate(a,50); fun(a,b,50); outdate(b,10); getch(); } 函数之间对一维数组和一维数组的元素的引用及一维数组实例720104.9 已知存放在a数组中的
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 学习 笔记 数组 函数