指针(C语言程序设计习题解答与上机指导)
1.以下说法正确的是()
A.一个变量的地址称为该变量的指针
B.变量的地址和指向它的指针变量的地址是相同的
C.指针变量的指向一旦确定就不能改变
D.不能定义两个指针变量指向同一个变量
答案:A
2.执行下面程序的输出结果为()
int m=1,j,+p=&m;
for (j=0;j<3;j++)
*p=*p+j;
printf(“%d,%d”,m,*p);
A. 1,4
B. 4,4
C.1,1
D.4,1
答案:B
3.若有“int a[6],*p;p=a;”,则不能正确对数组元素进行引用的是()
A.a[0]
B. *p
C. *(p+2)
D. p+2
答案:D
4.下列语句正确的是()
A. char a[]=”dcba”;
B. char a[10];a[]=”dcba”;
C. char *p;*p=”dcba”;
D. char a[10];a=”dcba”;
答案:A
5.若有“char *a[2]={“321”,“654”};”,以下说法正确的是()
A.数组a为2*4的二维数组
B.可以用puts(*a[0]);输出“321”
C.a[0]的值为“321”的首地址
D.定义错误
答案C
6.设有定义:float x,*p= &x;则下列表达式中错误的是()
A.*&p B. *&x C. &*p D. &*x
答案:D
7.若定义short num[][3]={2,4,6,8,10,12};则num[1][1]的值是()
A.8 B.4 C.2 D.10
答案:D
8.设有定义语句“float s[10],*p1=s,*p2=s+9;”,则下列表达式中,不能表示数组s的合法数组元素的是()
A.*(p1--)B.*(++p1)C.*(--p2)D.*(++p2)
答案:D
9.设有:char s[3][8]={“1”,“21”,“321”},*p=s;则正确的语句是()
A.printf(“%s”,*(p+1*8+0))
B.puts(*(*(p+1)+0))
C.scanf(“%s”,*(*(p+1)+0))
D.gets(&s[1][1])
答案:D
10.执行下列程序段后,*(p+5)的值是()
static char s[ ]=”Hello ”;
char *p;
p=s;
A.‘o ’
B.‘\0’
C.‘o ’的地址
D.不确定的值
答案:B
11. 以下程序的输出结果是()
#include “stdio.h ”
void main(void)
{
static int a[]={1,2,3,4,5,6},*p;
p=a;*(p+3)+=2;
printf(“%d,%d\n ”,*p,*(p+3));
}
A.0,5
B.1,5
C.0,6
D.1,6
答案:D
12. 在以下定义中,标识符p ()
int (*p )[3];
A. 定义不合法
B. 是一个指针数组名,每个元素是一个指向整型变量的指针
C. 是一个指针,它指向一个具有三个元素的一维数组
D. 是一个指向整型变量的指针
答案:C
13. 以下程序的输出结果是()
char *s=”ABCD ”,*p;
for(p=s;*p;p++)
printf(“%s\n ”,p);
答案:A
14. 下面程序的输出结果是()
#include
void main(void)
{ int n=6,*p=&n;
*p=8;
printf(“%d\n ”,n);
}
A.8
B.6
C.7
D.不确定
答案:A
15. 下面程序的输出结果是()
#include
void main(void)
A. ABCD
BCD
CD
D B. A B C D C. D C B A D. ABCD ABC AB A
{
int a=3,b=6,c=9;
int *pa=&a,*pb=&b,*p;
*(p=&c)=*pa*(*pb);
printf(“%d\n”,c);
}
A.8
B.18
C.27
D.9
答案:B
16.下面程序的输出结果是()
#include
void main( void )
{
char a[]={0,1,2,3,4,5,6,7,8,9},*p=a;
printf(“%d,%d\n”,*p+3,*(p+6));
}
A.2,2
B.3,5
C.3,6
D.3,7
答案:C
17.下面程序的输出结果是()
#include
void main(void)
{ int a[]={2, 4,6,8,10};
int *p=&a[4];
printf(“%d\n“,*--p);
}
A. 10
B.9
C.7
D.8
答案:D
18.若char s[10];s=“abcd”;printf(“%s”,s);程序的输出结果是()
A.abcd B.a C.dcba D.编译错误
答案:D
二、填空题
1.若定义int a[][3]={{1,2,3},{4,5,6}},(*p)[3]=a;则表达式*(*p+1)的值是 2 。2.若定义char s[5][10],*p=s;则使用p来表示数组元素s[2][3]的表达式是*(p+2*10+3)。3.数组名代表地址常量。指针代表地址变量。
4.设有char s[]=“123456”,*p=s+1;则表达式“*p+1”值对应的字符是 3 。
5.对于数组x[5][5],*(x+2)+3表示&x[2][3] ,*(x[3]+2)表示x[3][2] 。
6.设有char *s=“ABCD”,则printf(“%s”,s)的输出是ABCD ;而printf(“%c”,*s)的输出是 A 。
7.将字符数组s1中的字符复制到字符数组s2中。
#include
main()
{
char s1[80],s2[80],*p1,*p2;
gets s1 ;p1=s1;p2=s2;
while(*p2++=*p1++);
printf(“s2=%s”, s2 );
}
8.将输入的字符串按逆序打印出来。例如,输入abcd,则按dcba顺序打印出来。#include
#include
main()
{
char *str,s[20]; int n ;
str= s ;
scanf(“%s”,str);
n=strlen(str);
while(--n>=0)
{
str=&s[ n ];
printf(“%c”,*str);
}
}
关于堆栈和指针 堆栈是一种执行“后进先出”算法的数据结构。 设想有一个直径不大、一端开口一端封闭的竹筒。有若干个写有编号的小球,小球的直径比竹筒的直径略小。现在把不同编号的小球放到竹筒里面,可以发现一种规律:先放进去的小球只能后拿出来,反之,后放进去的小球能够先拿出来。所以“先进后出”就是这种结构的特点。 堆栈就是这样一种数据结构。它是在内存中开辟一个存储区域,数据一个一个顺序地存入(也就是“压入——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++中的一个类是定义在堆栈上的,就使用"."开访问它的成员。如果是定义在堆上的,就使用"->"指针来开访问。但在,"->"操作符也可以用在堆栈上的类。 什么是指针? 和其它变量一样,指针是基本的变量,所不同的是指针包含一个实际的数据,该数据代表一个可以找到实
1、使用选择法、冒泡法对10个数进行排序,并输出排序前后的数列。 n k=0; m t=0; //用于记录出列顺序 while(t
25 36 78 13 12 26 88 93 75 18 22 32 56 44 36 58 然后执行以下操作: ①输出矩阵两个对角线上的数; ②分别输出各行和各列的和; ③交换第一行和第三行的位置; ④交换第二列和第四列的位置; ⑤输出处理后的数组。 #include<> #define SIZE 4 void main() { int a[SIZE][SIZE]={{25,36,78,13},{12,26,88,93},{75,18,22,32},{56,44,36,58}}; int i,j,t,sum; //输出二维数组 printf("二维数组:\n"); for(i=0;i 一、指针:内容是指示一个内存地址的变量;类型是指示编译器怎么解释指针内容指向地址中的内容,以及该内存区域有多大; 例子: [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/064785531.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/064785531.html, 一、单项选择题 1.(A)是构成C语言程序的基本单位。 A、函数 B、过程 C、子程序 D、子例程 2.C语言程序从C开始执行。 A) 程序中第一条可执行语句B) 程序中第一个函数 C) 程序中的main函数D) 包含文件中的第一个函数 3、以下说法中正确的是(C)。 A、C语言程序总是从第一个定义的函数开始执行 B、在C语言程序中,要调用的函数必须在main( )函数中定义 C、C语言程序总是从main( )函数开始执行 D、C语言程序中的main( )函数必须放在程序的开始部分 4.下列关于C语言的说法错误的是(B )。 A) C程序的工作过程是编辑、编译、连接、运行 B) C语言不区分大小写。 C) C程序的三种基本结构是顺序、选择、循环 D) C程序从main函数开始执行 5.下列正确的标识符是(C)。 A.-a1 B.a[i] C.a2_i D.int t 6.下列C语言用户标识符中合法的是(B)。 A)3ax B)x C)case D)-e2 E)union 7.下列四组选项中,正确的C语言标识符是(C)。 A)%x B)a+b C)a123 D)123 8、下列四组字符串中都可以用作C语言程序中的标识符的是(A)。 A、print _3d db8 aBc B、I\am one_half start$it 3pai C、str_1 Cpp pow while D、Pxq My->book line# His.age 9.C语言中的简单数据类型包括(D)。 A、整型、实型、逻辑型 B、整型、实型、逻辑型、字符型 C、整型、字符型、逻辑型 D、整型、实型、字符型 10.在C语言程序中,表达式5%2的结果是C。 A)2.5 B)2 C)1 D)3 11.如果int a=3,b=4;则条件表达式"a 数组练习解答 1定义一个名为 a 的单精度实型一维数组 ,长度为 4,所有元素的初值均为 0的数定义语句就是 【分析】按照一般数据定义语句的格式 ,可以直接写出方法一(参瞧答案);考虑到所有元素均赋初值时可 以省略数组长度,可以写出方法二(参瞧答案);考虑到不省略数组长度,给部分元素赋初值时,所有未赋初 值的元素均有空值(对数值型数组来说,初值为0),可以写出方法三(参瞧答案);考虑到选用静态型,不赋 初值所有元素也自动赋予。空值 (对数值型数组来说,初值为0),可以写出方法四(参瞧答案)。 【答案】方法一 :float a[4] = (0.0,0.0,0.0,0.0}; 方法二:float a[] = ( 0.0,0.0,0.0,0.0}; 规定,定义字符型数组时不允许直接使用 "字符常量"的方式赋初值,所以备选答案②也就是错误的。 备选答案③符合题意。【答案】③ 6定义一个名为"s"的字符型数组,并且赋初值为字符串"123"的错误语句就是() ① char s[]={ '1','2','3',' \0 '}; ② char s 「」={"123"}; ③ char s[]={"123\n"}; ④ char s[4]={'1','2','3'}; 【分析】备选答案①中省略了数组长度 ,所以每个元素都赋了初值,共计4个元素,初值依次为T '3'、’ \0',最后一个元素的值为字符串结束标记 ,所以数组S 中存放的就是字符串"123",该答案不符合 题意(即正确的);备选答案③中直接赋予字符串作为初值所以数组 s 的长度为4,其中的初值就是字符串 "123",不符合题意(即正确的);备选答案③中也就是给数组 s 赋予字符串的初值,但就是字符串不就是 方法三:float a[4]= {0.0}; 方法四:static float [4]; 2下列数组定义语句中,错误的就是() ① char x[1] = 'a'; ② auto char x[1]={0}; ③ static char x[l]; ④ char x[l]; 【分析】显然答案①中给字符型数组赋初值的格式不对 以 备选答案①就是符合题意的答案。 【答案】① 3用"冒泡排序法"对n 个数据排序,需要进行n 一 1 较,小者调上;该操作反复执行 n- k 次。现在假设有 则利用"冒泡排序法"执行第2步后的结果就是 【分析】开始排序前的排列执行第 4 1 - 3 : (不能直接赋予字符常量,必须用花括号括住),所 步。其中第k 步的任务就是:自下而上,相邻两数比 4个数据:4、l 、3、2要排序,假定4为上、2为下, O 1步后的排列执行第 2步后的排列 1 2 4 2 【答案】l 、2、4、 3 4用"选择排序法"对n 个数据排序,需要进行n-1 据中寻找最小数,与第k 个数据交换。现在假设有 行第2步后的结果就是 ____________________ 【分析】 开始排序前的排列为: 4 执行第1步后的排列为: 执行第2步后的排列为: 【答案】1、2、3、4 5下列数组定义语句中,正确的就是() ① int a[][]={1,2,3,4,5,6}; ② char a[2] ③ int a[][3]= {1,2,3,4,5,6}; ④ static int a[][] 【分析】C 语言规定,二维数组定义时不允许省略第二维的长度 步。其中第k 步的任务就是:在第k 个数据到第n 个数 4个数据:4、 1、 3、2要排序,则利用"冒泡排序法"执 「3] = 'a','b'; ={{1,2,3},{4,5,6}}; ,所以备选答案①④就是错误 C 语言还 显然 、'2'、 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); } 实验4 数组 一.实验目的: 1.掌握一维数组的定义、赋值和输入输出的方法; 2.掌握字符数组定义、初始化、赋值的方法; 3.了解常见的字符串函数功能及其使用方法; 4.掌握二维数组的定义与引用。 二.实验内容: 1.编写程序,输入10个整数存入一维数组,统计输出其中的正数、负数和零的个数。 2.编写程序,输入10个整数存入一维数组,再按逆序重新存放后再输出。 3.编写程序,输入10个整数存入一维数组,对其进行升序排序后输出。 4.编写程序,求二维数组中元素的最大值和最小值。 5.编写程序,求一个4×4矩阵中所有元素之和。 6.编写程序:从键盘上输入一字符串,统计输出该字符串中的字母字符、数字字符、空格以及其他字符的个数。 7.编写程序:从键盘上输入一字符串,并判断是否形成回文(即正序和逆序一样,如“abcd dcba”)。 8. 产生一个由10个元素组成的一维数组并输出,数组元素由随机数(0-99)构成。 9. 产生一个由10个元素组成的一维数组,数组元素由随机数(0-99)构成。按照升序排列并输出。再输入一个数,按原来的规律将其插入并输出。 页脚内容1 10. 产生一个由10个元素组成的一维数组,数组元素由随机数(0-99)构成。按照升序排列并输出。再输入一个数,要求找出该数是数组中的第几个元素,如果不在数组中,则输出找不到。 11. 找出一个二维数组中的鞍点,即该位置上的元素在该行最大,在该列最小。可能没有鞍点。 12. 编程输出杨辉三角。(要求输出10行)(杨辉三角:每行端点与结尾的数为1.每个数等于它上方两数之和。每行数字左右对称,由1开始逐渐变大) 13. 输入一行字符,统计大写字母、小写字母、数字、空格以及其它字符个数。 14. 编写程序,将两个字符串连接起来,不用strcat。 15. 编写程序实现strcpy函数功能。 16. 编程实现strlen函数功能。 17. 编程求2-4+6-8…-100+102的值。 18. 假设某人有100,000现金。每经过一次路口需要进行一次交费。交费规则为当他现金大于50,000时每次需要交5%如果现金小于等于50,000时每次交5,000。请写一程序计算此人可以经过多少次这个路口。 19. 输入若干个正整数,以0结束,将其中大于平均值且个位为5的数排序后输出。(按由大到小的顺序排序) 20. 输入一个字符串,将其中ASCII码值为基数的字符排序后输出。(按由小到大的顺序) 21. 输入一个以回车结束的字符串(少于80个字符),滤去所有的非16进制字符后,组成一个新字符串(16进制形式),然后将其转换为10进制数后输出。 22. 读入一个正整数n(1<=n<=6),再读入n阶矩阵,计算该矩阵除副对角线、最后一行、最后一列 页脚内容2 GetMemory的典型例子 2010-01-13 18:24 520人阅读评论(2) 收藏举报//NO.1:程序首先申请一个char类型的指针str,并把str指向NULL(即str里存的是NULL的地址,*str为NULL中的值为0),调用函数的过程中做了如下动作:1申请一个char 类型的指针p,2把str的内容copy到了p里(这是参数传递过程中系统所做的),3为p指针申请了100个空间,4返回Test函数.最后程序把字符串hello world拷贝到str 指向的内存空间里.到这里错误出现了!str的空间始终为NULL而并没有实际的空间.深刻理解函数调用的第2步,将不难发现问题所在! void GetMemory(char *p) { p = (char*)malloc(100); } void Test(void) { char *str = NULL; GetMemory(str); strcpy(str, "hello world"); printf(str); } //请问运行Test函数后会是什么样的结果? //NO.2:程序首先申请一个char类型的指针str,并把str指向NULL.调用函数的过程中做了如下动作:1申请一数组p[]并将其赋值为hello world(数组的空间大小为12),2返回数组名p付给str指针(即返回了数组的首地址).那么这样就可以打印出字符串"hello world"了么?当然是不能的!因为在函数调用的时候漏掉了最后一步.也就是在第2步return数组名后,函数调用还要进行一步操作,也就是释放内存空间.当一个函数被调用结束后它会释放掉它里面所有的变量所占用的空间.所以数组空间被释放掉了,也就是说str所指向的内容将不确定是什么东西. char *GetMemory(void) { char p[] = "hello world"; return p; 6.1.1 Fibonacci数列 /* Fibonacci数列递推求解 */ main() {int k,n; long s,f[50]; printf("求数列的第n项与前n项和,请输入n:"); scanf("%d",&n); f[1]=1;f[2]=1;s=2; /* 数组元素与和变量赋初值 */ for(k=3;k<=n;k++) {f[k]=f[k-1]+f[k-2]; /* 实施递推 */ s+=f[k];} /* 实施求和 */ printf("F数列第%d项为:%ld\n",n,f[n]); printf("F数前%d项之和为:%ld\n",n,s); } 6.1.2 幂序列 /* 幂序列程序 */ main() {int k,n; long a,b,s,f[100]; printf("求数列的第n项与前n项和,请输入n:"); scanf("%d",&n); a=2;b=3;s=0; for(k=1;k<=n;k++) {if(a else {f[k]=b;b=b*3;} /* 用3的幂给f[k]赋值 */ s+=f[k];} printf("数列的第%d项为:%ld\n",n,f[n]); printf("数列的前%d项之和为:%ld\n",n,s); } 6.1.3 双关系递推数列 /* 双关系2x+1,3x+1递推 */ main() {int n,i,j,h,m[1500]; m[1]=1; scanf("%d",&n); for(i=1;i<=n;i++) {m[2*i]=2*m[i]+1;m[2*i+1]=3*m[i]+1; for(j=i+2;j<=2*i+1;j++) {if(m[i+1]>m[j]) /* m(i+1)与m(j)比较 */ {h=m[j]; m[j]=m[i+1];m[i+1]=h;} /* 交换,使m(i +1)最小 */ if(m[i+1]==m[j]) m[j]=20000+j;}} /* 置m(j)为一出界大数,以避免重复 */ for(i=1;i<=n;i++) {printf(" %4d",m[i]);C语言中指针、数组和引用例子实例
C语言练习题(带答案)
c语言数组习题
C语言数组指针的小例子
C语言数组编程题
c语言指针GetMemory经典例子
C语言数组例题
c语言数组例题