main()
{int x=30,=20;
printf(“(1)x=%d,y=%d\\n”,x,y); swap(&x,&y);
printf(“(4)x=%d,y=%d\\n”,x,y); }
Swap(int *a,int *b) {int t;
Printf(“(2)x=%d,y=%d\\n”,x,y); t=*a;*a=*b;*b=t;
printf(“(3)x=%d,y=%d\\n”,x,y); }
2) 例如:编写含数order( int *a,int *b)
使调用含数中的第一个实参总是存放两个数中的最小数;第二个参数存放两个中较大的数。 swap(int *x, int *y) {int t;
t=*x;*x=*y;*y=t; }
order(int *a,int *b) {if(*a>*b)swap(a,b);} main() {int x,y;
scanf(“%d%d”,&x,&y); printf(“x=%d y=%d ”,x,y); order(&x,&y);
printf(“x=%d y=%d\\n”,x,y); }
2. 函数返回地址值
函数值的类型可以是简单的数据类型,还可以为指针类型。例如:以下函数把两个整数形参中较大的那个数的地址作为函数值返回。
int *fun(int *a,int *b) { if(*a>*b) return a; return b; } main()
{int *p,i,j;
scanf(“%d%d”,&i,&j); p=fun(&i,&j);
printf(“i=%d,j=%d,*p=%d\\n”,i,j,*p); }
知识要点:
1.)设已有定义:float x;则以下对指针变量p进行定义且赋初值的语句中正确的是(D)
A) float *p=1024; B) int *p=(float x); C) float p=&x; D) float *p=&x; 2.)有以下程序
#include
*p=&n;
printf(“Input n:”); scanf(“%d”,&p); printf(“output n:”); printf(“%d\\n”,p); }
该程序试图通过指针p为变量n读入数据并输出,但程序有多处错误,以下语句正确的是 (A) A)int n,*p=NULL; B)*p=&n; C)scanf(“%d”,&p) D)printf(“%d\\n”,p);
3) 若有说明:int n=2,*p=&n,*q=p;则以下不正确的是
A) p=q B) *p=q C) n=*q D)p=n 答案[A]
4) 设有定义int n,*k=&n; 以下语句将利用指针变量k读取变量n 中的内容,请将语句补充完整:
scanf(\ printf(\
答案[k],[*k]
第 21 页 共 38 页
5)下面程序运行的结果是________ void f(int *a, int *b ) { int *t; t=a;a=b;b=t; } main( )
{int x=3,y=5,*p=&x,*q=&y; f(p,q);
printf(\答案3 5
6) 以下程序段的输出结果是______ int *p,a;
a=100;p=&a; a=*p+10; printf(\
分析:考察了指针赋值的基本概念和 答案:110
7) 若有以下定义和语句 #include
A) *q=0; B) w=p; C) *p=a; D) *p=*w 答案:A
8) 编写函数f( int *a, int *b),是调用函数中的第一个 实参总是存放两个数中较大的一个。
#include
t=*a;*a=*b;*b=t; }
void f( int *a, int *b) { if(*a>*b) f1(a,b); } main( )
{ int x,y;
scanf(\ f(&x,&y);
printf(\ }
9)若有定义:int x,*p; 则正确的赋值表达式 A)p=&x B)p=x C)*p=&x D)*P=*x 10 .#include
Void sub( double x, double *y, double *z) {*y=*y-1.0;*z=*z+x;} main( )
{ double a=2.5,b=9.0,*pa,*pb; Pa=&a;pb=&b;
sub(b-a,pa,pa);printf(“%f\\n”,a);
A9.000000 B1.500000 C 8.000000 D 10.500000
} 分析:本题考察了指针的赋值原理和指针的定义。
基础概念。 }
第二部分:上机题
1. 编写程序:功能是对传送过来的两个双精度数求出他
们的差,并通过形参传送给调用函数。 2. 利用指针,对传递来的两个数进行交换。
3. 编写函数,int *fun(int * ,int *),其功能是对传递过来
的两个整数进行比较,函数返回其中最的数的地址值。(参照课本8.5.3)
第九章函数
知识要点:
1一维说组的定义:
1) 当数组中每个元素只带一个下标时,称
这样的数组为一维数组。 2) 定义一维数组的一般形式为: 类型名 数组名[ 常量表达式]…….. 例如:int a[8]; 说明如下:
第 22 页 共 38 页
(1) 定义一个名为a的一维数组。 (2) 方括号中8规定a数组中有8个
元素(a[0]到a[7])
(3) 类型名int 规定a数组中每个元
素为整型,且每个元素中只能存放整型数。
(4) 每个元素只有下标且第一个元
素的下标总为0 (5) C语言编译程序为a数组开辟8
个连续的存储单元。
a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] 3) (1): 在定义数组语句中,可以有多个数组说明符,他们用逗号隔开。
例如:double a[22],b[100], c[5]; (2):数组说明符和普通变量名,可以同时出现在一个类型的定义语句中。 2.一维数组的引用
1)引用形式如下:
数组名[下标表达式]例如:double a[8];则a[0],a[j],a[i+k] 都是合法的。 注意:a[i+k]中i+k是下标表达式不是两个下标
2.
(1):一个数组元素实际上就是一个变量名。代表内存中的一个存储单元。
(2):一个数组不能整体引用,数组名中存放的是一个地址常量,它代表整个数组的首地址。 (3)在引用数组元素时,数组元素下标表达式必须是整数,下标表达式下限为0。系统并不会自动检验数组元素下标是否越界,因此编程时候要多注意。
3.一维数组的初始化。
1) 在定义语句中给所定义数组赋初值 初值放在赋值号后的花括号中,数值类型与说明类型一致,初值间用逗号隔开,系统
将自动按顺序从a[0]开始依次给a数组中元素。如int a[8]={0,1,2,3,4,5,6,7};
2) (1)当初值少于元素个数时,后面元素赋给0。字符补给‘\\0’
例如:int a[10]={0};十个元素都赋初值0
char a[5]={?A?}; char a[5]={?A?,?\\0?, ?\\0?, ?\\0?, ?\\0?,}; (2)当初值多于元素个数,系统给出出错信息。
3)可以通过赋初值来定义数组的大小 例如:int a[]={0,0,0,0,0,0};
int a[6]={0};
4举例说明:
(见课本)编写程序,定义一个含有30
个元素的int 类型数组,依次给数组赋 1 3 5 7 9….然后按每行10个顺序输出,最后在按每行10个逆序输出。
第二节:一维数组和指针
1)数组和指针比较记忆:
(1) 指针变量的地址(每个变
量的地址就是该变量的
第一个字节的地址)数组名的地址值,就是该数组
第一个元素的地址。
(2) 指针变量有基类型,相当
于数组的类型名
(3) 指针变量的地址值是不
可以改变,因此不可以给
数组重新赋值。p=&a;
语句a=&x;或a++;都是非法
的,因为不能给a重新赋值,一但定义,a永远指向a数组的首地址。
2)虽然不可以改变a 中的 内容,
但可以对数组名加一个整数的办法,来依次表达该数组中不同元
素的地址。Int a[10],*p,x;
第 23 页 共 38 页
例如:(k为int ) p=a+k; for(k=0;k>10;k++)
scanf(“%d” ,a+k);
语句p=&a[0]== >p=a;指向a数组首地址:
以下语句是等价的:
for(p=a,k=0;k>10;k++) p++; for(p=a,k=0;k>10;k++) {scanf(“%d”,p);p++}
for(p=a,k=0;k>10;k++) scanf(“%d”,p++);
for(p=a;p-a<10;p++) scanf(“%d”,p);
2. 通过数组首地址,指针,带下标的指针引用
一维数组
1)
第三节函数之间对一维数组和数组元素的引用及一维数组实例:
1. 数组元素作为实参:
在调用函数时,数组元素可以作为实参传递给形参,每个数组元素实际代表内存中的一个存储单元和普通变量一样,对应的形参必须是类型相同的变量。
2. 数组名作为实参
数组元素的值,可以传递给该变量,
在函数中只能对用该变量进行操作,而不能直接引用对用数组元素,数组名也可以作为实参传送,,但数组名本身是一个地址值,因此对应的形参应该是一个指针就变量来引用调用函数中对应的数组元素,从而达到对调用函数中对应数组元素进行操作。 例如:编写程序:通过函数给数组输入若干大于等于0的整数,用负
*&a[i] *(a+i)
(p=a;||p=&a[0]; ) *(p+i)
a[i] p[i]
数作为结束标志,调用函数输出该数
数组a 组中的数据。 若有:p=a; (a[i] *(a+i) p[i] *(p+i) ) 1)当数组名作为实参时,对应
以上是数组元素a[i],一对方括号不仅是表示数组元素的记号,也是一种运算符。 看下面的式子: &a[i] a+i p+i 以上是a[i]的地址
*(p--) a[i--] *--p a[--i]
(2)a和p的区别:a是不可以改变的,p中的地址值却是可以改变的,
因此 a++;a=p,p=&a非法 p++,p=a,p=&a[i] 合法 3)逐个输出a数组中元素的值。 for(k=0;k<10;k++) printf(“M”.*(a+k));
for(k=0;k<10;k++) printf(“M”.a[i]); for(p=a,k=0;k<10;k++) printf(“M”,*(p+k));
for(k=0;k<10;k++) printf(“M”.p[i]);
第 24 页 共 38 页
的形参可以是:
(1) fun (int *a) (2) fun(int a[ ]) (3) fun(int a[M])
2)此处*(a+i) ====> a[i]
3.数组元素地址作为实参:
当数组元素地址作为实参时,因为是
地址值,所以对应的形参也应该是类型相同的指针变量
例如:编写程序,对具有10个元素的char
类型数组,从下标为4的元素开始,全部置‘*’,保持前四个元素内容不变。
注:setsar 函数首部可写为:
Setsar(char a[ ],int n) 或 setsar (char
a[M-B], int n) *(a+i)可以写为 a[i]
程序(略):
4.函数的指针形参和函数体中数组的区别:
例如:以下程序,形参a指向w数组,函