指针练习题
(一)选择题
1.若有以下定义,则对a数组元素的正确引用是_________.
int a[5],*p=a;
a)*&a[5] b)a+2 c)*(p+5) d)*(a+2)
2.若有定义:int a[2][3],则对a数组的第i行j列元素地址的正确引用为______.
a)*(a[i]+j) b)(a+i) c)*(a+j) d)a[i]+j
3.若有以下定义,则p+5表示_______.
int a[10],*p=a;
a)元素a[5]的地址b)元素a[5]的值
c)元素a[6]的地址d)元素a[6]的值
4.下面程序段的运行结果是_________.
char *s="abcde";
s+=2;printf("%d",s);
a)cde b)字符'c' c)字符'c'的地址d)无确定的输出结果
5.设p1和p2是指向同一个字符串的指针变量,c为字符变量,则以下不能正确执行的赋值语句是__b______.
a)c=*p1+*p2; b)p2=c(c为变量)c)p1=p2 d)c=*p1*(*p2);
6.以下正确的程序段是_________.
a)char str[20]; b)char *p;
scanf("%s",&str); scanf("%s",p);
c)char str[20]; d)char str[20],*p=str;
scanf("%s",&str[2]); scanf("%s",p[2]);
7.若有说明语句
char a[]="It is mine";
char *p="It is mine";
则以下不正确的叙述是________.
a)a+1表示的是字符t的地址
b)p指向另外的字符串时,字符串的长度不受限制
c)p变量中存放的地址值可以改变
d)a中只能存放10个字符
8.下面程序的运行结果是_______.
#include
#include
main()
{
char *s1="AbDeG";
char *s2="AbdEg";
s1+=2;s2+=2;
printf("%d\n",strcmp(s1,s2));
}
a)正数b)负数c)零d)不确定的值
9.下面程序的运行结果是_______.
#include
#include
fun(char *w,int n)
{char t,*s1,*s2;
s1=w;s2=w+n-1;
while(s1 } main() {char *p; p="1234567"; fun(p,strlen(p)); puts(p); } a)7654321 b)1714171 c)1711717 d)7177171 10.变量的指针,其含义是指该变量的b_________. a)值b)地址 c)名d)一个标志 11.若有语句int *point,a=4;和point=&a;下面均代表地址的一组选项是__d___. a)a,point,*&a b)&*a,&a,*point c)*&point,*point,&a d)&a,&*point ,point 12.若有说明;int *p,m=5,n;以下正确的程序段的是_____d___. a)p=&n; b)p=&n; scanf("%d",&p); scanf("%d",*p); c)scanf("%d",&n); d)p=&n; *p=n; (*p没有定义)*p=m; (二)填空题 1.以下程序的功能是:通过指针操作,找出三个整数中的最小值并输出。 请填空。 #include "stdlib.h" main() {int *a,*b,*c,num,x,y,z; a=&x;b=&y;c=&z; printf("输入3个整数:"); scanf("%d%d%d",a,b,c); printf("%d,%d,%d\n",*a,*b,*c); num=*a; if(*a>*b)______; if(num>*c)______; printf("输出最小整数:%d\n",num); } 2.下面程序段的运行结果是________. char s[80],*sp="HELLO!"; sp=strcpy(s,sp); s[0]='h'; puts(sp); 3.下面程序段的运行结果是________. char str[]="abc\0def\0ghi",*p=str; printf("%s",p+5); 4.下面程序的功能是将两个字符串s1和s2连接起来。请填空。 #include main() {char s1[80],s2[80]; gets(s1); gets(s2); conj(s1,s2); puts(s1); } conj(char *p1,char *p2) {char *p=p1; while(*p1)______; while(*p2){*p1=______;p1++;p2++;} *p1='\0'; __________; } 5.若有定义:int a[]={2,4,6,8,10,12},*p=a;则*(p+1)的值是______. *(a+5)的值是_________. 6.若有以下定义:int a[2][3]={2,4,6,8,10,12};则a[1][0]的值是_____. *(*(a+1)+0))的值是________. 7.以下程序将数组a中的数据按逆序存放,请填空。 #define M 8 main() {int a[M],i,j,t; for(i=0;i i=0;j=M-1; while(i { t=*(a+i);________;*(_______)=t; i++;j--; } for(i=0;i } 8.若有定义:int a[3][5],i,j;(且0<=i<3,0<=j<5),则a数组中任一元素可用 五种形式引用。它们是: (1)a[i][j] (2)*(a[i]+j) (3)*(*______); (4)(*(a+i))[j] (5)*(____+5*i+j) 9.下面程序的运行结果是_________. main() {char *a[]={"Pascal","C language","dBase","Coble"}; char (**p)[]; int j; p=a+3; for(j=3;j>=0;j--)printf("%s\n",*(p--)); } (三)程序设计题(要求用指针的方法完成) 1.编写程序,交换数组a和数组b中的对应元素。 2.有10个数围成一圈,求出相邻三个数之和的最小值。 3.产生动态数组。输入数组大小后,通过动态分配内存函数malloc产生数组。4.编写程序,将一个字符串反向存放。 5.输入一串英文文字,统计其中字母(不区分大小写)的数目。 C语言程序设计实验报告 1实验目的 (1)掌握指针的概念,会定义和使用指针变量; (2)能正确使用变量的指针和指向变量的指针变量; (3)能正确使用数组的指针和指向数组的指针变量; (4)能正确使用字符串的指针和指向字符串的指针变量; 2实验内容 将一个任意整数插入到已排序的整形数组中,插入后,数组中的数仍然保持有序;要求: (1)整形数组直接由赋值的方式初始化,要插入的整数有scanf()函数数入;(2)算法实现过程采用指针进行处理; (3)输入原始数据以及插入整数后的数据,并加以说明; 3算法描述流程图 4源程序 #include for(i=n-1;a[i]>=w;i--) { a[i+1]=a[i]; } a[i+1]=m; 这一步没有注意a[i++]=m和a[i+1]=m中i++和i+1不同,a[i++]=m是先将的值赋给a[i],然后在执行自增;而在实验过程中忽略了这一点,造成了不必要的麻烦; 8实验心得 通过这次指针实验掌握了指针的概念,会定义和使用指针变量,并且能利用指针来简单化一些问题,给以后的编程带来了很大的便利; 关于堆栈和指针 堆栈是一种执行“后进先出”算法的数据结构。 设想有一个直径不大、一端开口一端封闭的竹筒。有若干个写有编号的小球,小球的直径比竹筒的直径略小。现在把不同编号的小球放到竹筒里面,可以发现一种规律:先放进去的小球只能后拿出来,反之,后放进去的小球能够先拿出来。所以“先进后出”就是这种结构的特点。 堆栈就是这样一种数据结构。它是在内存中开辟一个存储区域,数据一个一个顺序地存入(也就是“压入——push”)这个区域之中。有一个地址指针总指向最后一个压入堆栈的数据所在的数据单元,存放这个地址指针的寄存器就叫做堆栈指示器。开始放入数据的单元叫做“栈底”。数据一个一个地存入,这个过程叫做“压栈”。在压栈的过程中,每有一个数据压入堆栈,就放在和前一个单元相连的后面一个单元中,堆栈指示器中的地址自动加1。读取这些数据时,按照堆栈指示器中的地址读取数据,堆栈指示器中的地址数自动减1。这个过程叫做“弹出pop”。如此就实现了后进先出的原则。 堆栈是计算机中最常用的一种数据结构,比如函数的调用在计算机中是用堆栈实现的。 堆栈可以用数组存储,也可以用以后会介绍的链表存储。 下面是一个堆栈的结构体定义,包括一个栈顶指针,一个数据项数组。栈顶指针最开始指向-1,然后存入数据时,栈顶指针加1,取出数据后,栈顶指针减1。 #define MAX_SIZE 100 typedef int DATA_TYPE; struct stack { DATA_TYPE data[MAX_SIZE]; int top; }; 堆栈是系统使用是临时存储区域。它是后进先出的数据结构。 C++主要将堆栈用于函数调用。当函数调用时,各种数据被推入堆栈顶部;函数终止后的返回地址、传递给函数的参数、函数返回的结果以及函数中声明的局部变量等等。因此当函数A调用函数B调用函数C,堆栈是增长了,但调用完成后,堆栈又缩小了。 堆是一种长期的存储区域。程序用C++的new操作符分配堆。对new的调用分配所需的内存并返回指向内存的指针。与堆栈不同,你必须通过调用new明确的分配堆内存。你也必须通过调用C++的delete 操作符明确的释放内存,堆不会自动释放内存。 如果C++中的一个类是定义在堆栈上的,就使用"."开访问它的成员。如果是定义在堆上的,就使用"->"指针来开访问。但在,"->"操作符也可以用在堆栈上的类。 什么是指针? 和其它变量一样,指针是基本的变量,所不同的是指针包含一个实际的数据,该数据代表一个可以找到实 《C++指针》习题 学号姓名 一、选择题 1、有定义如下:int a[5], *p; 则下列描述错误的是B A.表达式p=p+1是合法的B.表达式a=a+1是合法的 C.表达式p-a是合法的D.表达式a+2是合法的 2、函数定义为Fun(int &i),变量定义n=100,则下面调用该函数正确的 是C A.Fun(20) B.Fun(20+n) C.Fun(n) D.Fun(&n) 3、若有说明int I,j=2,*p=&i;则能完成i=j赋值功能的语句是B A.i=*p; B.*p=*&j; C.i=&j; D.i=**p; 4、设已有定义char *st = "how are you";下列程序中正确的是A A.char a[11],*p;strcpy(p=a+1,&st[4]); B.char a[11];strcpy(++a,st); C. char a[11];strcpy(a,st); D. char a[],*p;strcpy(p=a[1],st+2); 5、设有数组int array[3][4],下列引用数组元素的方法中错误的是D A.array[i][j] B.*(*(array+i)+j) C. *(array[i]+j) D. *(array+i*4+j) 6、有定义int s[4][5],(*ps)[5];ps=s;则对数组s中元素引用的正确 的是C A.ps+1 B.*(ps+3) C. ps[0][2] D. *(ps+1)+3 7、设有说明int b[4][4],以下不能等价表示元素b[3][3]的是:B A.*&b[3][3] B.(*(*(b+3))+3) C.*(b[3]+3) D.*(*(b+3)+3) 8、若有说明"char *s[]={"234","5678","9012","3456","7890"};",则表达 式*s[1]> *s[3]比较的是B A."1234"和"9012" B.'5'和'3' C.'l'和'9' D."5678"和"3456" 9、设语句"char *s[]={"Student","Teacher","Father","Mother"},*ps=s[2];",执行语句"cout<<*s[1]<<','< 实验名称:指针使用 实验目的:熟悉指针的正确用法。 相关知识:1.指针的定义;2.指针的引用; 实验内容: (1) 调试下面程序,指出错误原因。 main ( ) { int x=10,y=5,*px,*py; px=py; px=&x; py=&y; printf(“*px=%d,*py=%d”,*px,*py); } (2)调试下面程序。 #include (3)调试下面程序。 #include 一、指针:内容是指示一个内存地址的变量;类型是指示编译器怎么解释指针内容指向地址中的内容,以及该内存区域有多大; 例子: [cpp] int i = 0; int * pi = &i; printf(“pi = %x \n”, pi); // 打印pi的内容: 0x2000 printf(“*pi= %d \n” , *pi); // 打印pi指向地址中的值: 5 printf(“&pi= %x \n”, &pi); // 打印pi的地址: 0x100 从汇编的角度来看,指针是这样的: int i = 0; 010E139E mov dword ptr [i],0 int * pi = &i; 010E13A5 lea eax,[i] 010E13A8 mov dword ptr [pi],eax 二、数组:是一个单一数据类型对象的集合。其中单个对象没有被命名,通过索引访问。 数组名和指针的区别:数组名的内涵在于其指代实体是一种数据结构,这种数据结构就是数组。数组名的外延在于其可以转换为指向其指代实体的指针,而且是一个指针常量。指向数组的指针则是另外一种变量类型,仅仅意味着数组的存放地址 注意:虽然数组名可以转换为指向其指代实体的指针,但是它只能被看作一个指针常量,不能被修改,如下:天骄无双:https://www.doczj.com/doc/bc4775470.html, [cpp] int intArray[10]; intArray++; // 错误 “指针和数组等价”说的是什么?索引操作相同,例如:p[2]; a[2]; 三、引用(reference)是一个对象的别名。用对象初始化引用后,对象的名字和引用都指向该对象; 引用是如何实现的?从汇编语言的角度来看,指针和引用是一样的: [cpp] int i = 0; 00E9139E mov dword ptr [i],0 int & ref = i; 00E913A5 lea eax,[i] 00E913A8 mov dword ptr [ref],eax int * pi = &i; 00E913AB lea eax,[i] 00E913AE mov dword ptr [pi],eax 指针和引用的区别(从C++使用角度来看): 不存在空引用 引用要初始化 引用初始化后,不能指向另一个对象 这是由编译阶段保证的。 备注:一个指向非常量的引用不能用字面值或者临时值初始化;但是一个指向常量的引用可以。天骄无双:https://www.doczj.com/doc/bc4775470.html, 习题解答 一、单项选择题 1.若定义了int n=2, *p=&n, *q=p;则下面【】的赋值是非法的。 A.p=q B. *p=*q C. n=*q D. p=n 【答案】D 2.若定义了double *p, a;则能通过scanf函数给输入项读入数据的程序段是【】。 A.p=&a; scanf(“%1e”,p); B. *p=&a; scanf(“%1f”,p); C. p=&a; scanf(“%f”,p); D. p=&a; scanf(“%1f”,a); 【答案】C 3.若定义了int a[10], i=3, *p; p=&a[5];下面不能表示为a数组元素的是【】。 A.p[-5] B. a[i+5] C. *p++ D. a[i-5] 【答案】D 4.若有如下定义: int n[5]={1,2,3,4,5},*p=n; 则值为5的表达式是【】。 A.*+5 B. *(p+5) C. *p+=4 D. p+4 【答案】C 5.设变量b的地址已赋给指针变量ps,下面为“真”的表达式是【】。 A.b==&ps B. b==ps C. b==*ps D. &b==&ps 【答案】C 6.设有以下定义和语句: int a[3][2]={1,2,3,4,5,6},*p[3]; p[0]=a[1]; 则*(p[0]+1)所代表的数组元素是【】。 A.a[0][1] B. a[1][0] C. a[1][1] D. a[1][2] 【答案】C 7.若定义了char *str=”Hello!”;下面程序段中正确的是【】。 A.char c[ ], *p=c; strcpy(p,str); B.char c[5], *p; strcpy(p=&c[1],&str[3]); C.char c[5]; strcpy(c,str); D.char c[5]; strcpy(p=c+2,str+3); 【答案】B 8.若有下面的程序段,则不正确的fxy函数的首部是【】。 main() { int a[20], n; … fxy(n, &a[10]); … } A.void fxy(int i, int j) B. void fxy(int x, int *y) C. void fxy(int m, int n[]) D. void fxy(int p, int q[10]) 【答案】A 9.不合法的带参数main函数的首部形式是【】。 C语言程序设计实验报告 1实验目得 (1)掌握指针得概念,会定义与使用指针变量; (2)能正确使用变量得指针与指向变量得指针变量; (3)能正确使用数组得指针与指向数组得指针变量; (4)能正确使用字符串得指针与指向字符串得指针变量; 2实验内容 将一个任意整数插入到已排序得整形数组中,插入后,数组中得数仍然保持有序; 要求: (1)整形数组直接由赋值得方式初始化,要插入得整数有scanf()函数数入; (2)算法实现过程采用指针进行处理; (3)输入原始数据以及插入整数后得数据,并加以说明; 3算法描述流程图 4源程序 #include for(i=n-1;a[i]>=w;i--) { a[i+1]=a[i]; } a[i+1]=m; 这一步没有注意a[i++]=m与a[i+1]=m中i++与i+1不同,a[i++]=m就是先将得值赋给a[i],然后在执行自增;而在实验过程中忽略了这一点,造成了不必要得麻烦; 8实验心得 通过这次指针实验掌握了指针得概念,会定义与使用指针变量,并且能利用指针来简单化一些问题,给以后得编程带来了很大得便利; 指针综合练习题 一、选择题 1.若有以下定义,则对a数组元素的正确引用是____d_____. int a[5],*p=a; a)*&a[5] b)a+2 c)*(p+5) d)*(a+2) 2.若有定义:int a[2][3],则对a数组的第i行j列元素地址的正确引用为__d____. a)*(a[i]+j) b)(a+i) c)*(a+j) d)a[i]+j 3.若有以下定义,则p+5表示___a____. int a[10],*p=a; a)元素a[5]的地址b)元素a[5]的值 c)元素a[6]的地址d)元素a[6]的值 4.设p1和p2是指向同一个字符串的指针变量,c为字符变量,则以下不能正确 执行的赋值语句是____b____. a)c=*p1+*p2; b)p2=c c)p1=p2 d)c=*p1*(*p2); 5.若有说明语句 char a[]="It is mine"; char *p="It is mine"; 则以下不正确的叙述是___d_____. a)a+1表示的是字符t的地址 b)p指向另外的字符串时,字符串的长度不受限制 c)p变量中存放的地址值可以改变 d)a中只能存放10个字符 二、填空题 1 指针变量保存了另一变量的(1)值,不可以任意给指针变量赋一个地址值,只能赋给 它(2)和(3)的地址。使用变量名来访问变量,是按(4)来直接存取变量称为(5)方式;而借助指针变量取得另一变量的地址,访问该变量称为(6)方式。 答案:(1)地址 (2)NULL (3)已经分配了内存的变量的地址 (4)按变量的地址 (5)直接访问 (6)间接访问 2 以下程序的功能是:通过指针操作,找出三个整数中的最小值并输出。 请填空。 void main() {int *a,*b,*c,num,x,y,z; a=&x;b=&y;c=&z; cou<<"输入3个整数:"; cin>>a>>b>>c; cout<<*a<<*b<<*c; num=*a; C语言实习报告 题目:指针及其应用 系别: 专业: 姓名: 学号: 日期: 一实验名称:指针及其应用 二实验目的: (1)掌握变量的指针及其基本用法。 (2)掌握一维数组的指针及其基本用法。 (3)掌握指针变量作为函数的参数时,参数的传递过程及其用法。 三实验内容: (1)运行以下程序,并从中了解变量的指针和指针变量的概念。 (2)运行以下程序,观察&a[0]、&a[i]和p的变化,然后回答以下问题: 1.程序的功能是什么? 2.在开始进入循环体之前,p指向谁? 3.循环每增加一次,p的值(地址)增加多少?它指向谁? 4.退出循环后,p指向谁? 5.你是否初步掌握了通过指针变量引用数组元素的方法? (3)先分析以下程序的运行结果,然后上机验证,并通过此例掌握通过指针变量引用数组元素的各种方法。 (4)编写函数,将n个数按原来的顺序的逆序排列(要求用指针实现),然后编写主函数完成: ①输入10个数; ②调用此函数进行重排; ③输出重排后的结果。 四分析与讨论: (1)指针的定义方法,指针和变量的关系。 定义方法: 数据类型 *指针变量名; 如定义一个指向int型变量的指针—— int *p; 则我们可以继续写如下代码—— int a = 4; p = &a; printf("%d", *p); 在这里,我们定义了一个变量a,我们把它理解为内存空间连续的4个字节(int型占用4字节),则这4个字节的空间保存着一个数4。&是取地址符号,即把变量a的地址(即这4个字节的首地址)赋给指针p (记住指针p的类型和变量a的类型要保持一致,否则的话,要进行类型转换)。这样子,指针p就保存着变量a的地址。我们如果把指针p当做内存空间里面另外一个连续的4个字节,那么这4个字节保存的数就是变量a的地址。printf("%d",*p)和printf("%d",a)的结果是一样的。这里的*是取变量符号(与&刚好作用相反,通过变量的地址找到变量),与定义时int *p的*号作用不同(定义时的*表示该变量是个 指针变量,而非是取它指向的变量)。 (2)数组和指针的关系。 指针与数组是C语言中很重要的两个概念,它们之间有着密切的关系,利用这种关系,可以增强处理数组的灵活性,加快运行速度,本文着重讨论指针与数组之间的联系及在编程中的应用。 1.指针与数组的关系 当一个指针变量被初始化成数组名时,就说该指针变量指向了数组。如: char str[20], *ptr; ptr=str; ptr被置为数组str的第一个元素的地址,因为数组名就是该数组的首地址,也是数组第一个元素的地址。此时可以认为指针ptr就是数组str(反之不成立),这样原来对数组的处理都可以用指针来实现。如对数组元素的访问,既可以用下标变量访问,也可以用指针访问。 2.指向数组元素的指针 若有如下定义: int a[10], *pa; pa=a; 则p=&a[0]是将数组第1个元素的地址赋给了指针变量p。 实际上,C语言中数组名就是数组的首地址,所以第一个元素的地址可以用两种方法获得:p=&a[0]或p=a。 这两种方法在形式上相像,其区别在于:pa是指针变量,a是数组名。值得注意的是:pa是一个可以变化的指针变量,而a是一个常数。因为数组一经被说明,数组的地址也就是固定的,因此a是不能变化的,不允许使用a++、++a或语句a+=10,而pa++、++pa、pa+=10则是正确的。由此可见,此时指针与数组融为一体。 3.指针与一维数组 理解指针与一维数组的关系,首先要了解在编译系统中,一维数组的存储组织形式和对数组元素的访问方法。 一维数组是一个线形表,它被存放在一片连续的内存单元中。C语言对数组的访问是通过数组名(数组的起始地址)加上相对于起始地址的相对量(由下标变量给出),得到要访问的数组元素的单元地址,然后再对计算出的单元地址的内容进行访问。通常把数据类型所占单元的字节个数称为扩大因子。 实际上编译系统将数组元素的形式a[i]转换成*(a+i),然后才进行运算。对于一般数组元素的形式:<数组名>[<下标表达式>],编译程序将其转换成:*(<数组名>+<下标表达式>),其中下标表达式为:下标表达式*扩大因子。整个式子计算结果是一个内存地址,最后的结果为:*<地址>=<地址所对应单元的地址的内容>。由此可见,C语言对数组的处理,实际上是转换成指针地址的运算。 数组与指针暗中结合在一起。因此,任何能由下标完成的操作,都可以用指针来实现,一个不带下标的数组名就是一个指向该数组的指针。 1、功能:输入6个学生的5门课程成绩,计算出每个学生的平均分和每门课程的平均分。 2、C语言实现代码:(其实就是用二维数组来实现的,二维数组的引用传递使用数组指针来完成) 复制代码代码如下: #include <stdio.h> #define STUDENT 5 #define SCORE 6 void input_array(float (*score)[STUDENT]); void avg_score(float (*score)[STUDENT]); void avg_course(float (*score)[STUDENT]); /** * calculate student average score and course average socore. */ int main(){ float a[SCORE][STUDENT]; input_array(a); avg_course(a); avg_score(a); } void input_array(float (*score)[STUDENT]){ int i, j; for(i=0; i<SCORE; i++){ printf("input the %d student score:", i+1); for(j=0; j<STUDENT; j++){ scanf("%f", score[i] + j); } } } void avg_course(float (*score)[STUDENT]){ int i,j; float s; for(j=0; j<STUDENT; j++){ printf("course%d ", j); } printf("n"); for(i=0; i<SCORE; i++){ s=0; for(j=0; j<STUDENT; j++){ printf("%f ", *(score[i] + j)); s += *(score[i] + j); } 编程题 1用指向数组的指针变量输出数组的全部元素 #includeC语言指针实验报告
关于堆栈和指针(指针例子解释很好)
《C++指针》习题参考答案
指针实验
C语言中指针、数组和引用例子实例
教材课后题答案-第6章_指针习题答案
C语言指针实验报告
指针综合练习题(带答案)
c语言指针实验报告
C语言数组指针的小例子
指针练习题与答案