C++实验报告

结课考试

实验报告(一)略

实验报告(二)

选择题

  1. 下列哪个类型函数不适合声明为内联函数___A.函数体语句较多__。
    原因:内联函数只有对于规模小且使用频繁的函数,才可大大提高运行速度!
  2. 对类中声明的变量,下列描述中正确的是__C.属于该类,某些情况下也可被该类不同实例所共享__。
    原因:静态成员变量可以被该类的不同实例所共享!
  3. 类的私有成员可在何处访问__D.本类的成员函数中___。
    原因:私有成员变量或方法只能在该类的成员函数中访问,外部访问需要通过该类对象调用共有成员函数访问
  4. 如果没有为一个类定义任何构造函数的情况下,下列描述正确的是__D.本类的成员函数中___。
    原因:若在声明定义类的时候没有定义构造函数,则编译器总是自动创建一个不带参数的构造函数,如果自定义了构造函数,则编译器不会在创建
  5. 一个类可包含析构函数的个数是__B.1个___。
    原因:析构函数没有返回值,没有函数类型,也没有函数参数,即不存在重载,如果用户不定义析构函数,编译器也会自动创建一个析构函数,所有只有一个
  6. 在编译指令中,宏定义使用哪个指令__B.#define___。
  7. 对于友元描述正确的是__B.友元不是本类的成员函数___。
    原因:友元函数不仅可以是一般函数(非成员函数),而且可以是另一个类中的成员函数

填空题

  1. 类的继承是指子类继承基类的___成员变量(属性)____和成员函数。
  2. __#include__指令指示编译器将一个源文件嵌入到带该指令的源文件之中。
  3. 将指向对象的指针作为函数参数,形参是对象指针,实参是对象的___地址值____。
  4. C++的面向对象特点包括____封装、继承、多态____。
  5. 头文件_ (的代码)会在main 函数之前执行。

简答题

  1. 子类析构时要调用父类的析构函数吗?
     子类析构时不需要,析构后调用父类析构函数,二者不同时,且子类析构在父类析构之前
  2. C++函数中值的传递方式有哪几种?

    1. 值传递
    2. 指针传递
    3. 引用传递
    4. 全局变量传递

程序题

1. 分析下面的程序,写出运行结果:

 #include <iostream>
using namespace std;
class Date
 {public:
   Date(int,int,int);
   Date(int,int);
   Date(int);
   Date();
   void display();
  private:
   int month;
   int day;
   int year;
 };
Date::Date(int m,int d,int y):month(m),day(d),year(y)
 { }
Date::Date(int m,int d):month(m),day(d)
 {year=2005;}
Date::Date(int m):month(m)
 {day=1;
  year=2005;
 }
Date::Date()
 {month=1;
  day=1;
  year=2005;
 }
void Date::display()
 {cout<<month<<"/"<<day<<"/"<<year<<endl;}
int main()
{
 Date d1(10,13,2005);
 Date d2(12,30);
 Date d3(10);
 Date d4;
 d1.display();
 d2.display();
 d3.display();
 d4.display();
 return 0;
 }
输出结果

10/13/2005
12/30/2005
10/1/2005
1/1/2005

2. 将第一题的第四行改为用默认参数,即Date(int=1,int=1,int=2005);分析程序有无问题。要求保留上一行给出的构造函数,同时能输出与上一题相同的结果。

#include <iostream>
using namespace std;
class Date
 {public:
   Date(int=1,int=1,int=2005);
   void display();
  private:
   int month;
   int day;
   int year;
 };
Date::Date(int m,int d,int y):month(m),day(d),year(y)
 { }
void Date::display()
 {cout<<month<<"/"<<day<<"/"<<year<<endl;}
int main()
{
 Date d1(10,13,2005);
 Date d2(12,30);
 Date d3(10);
 Date d4;
 d1.display();
 d2.display();
 d3.display();
 d4.display();
 return 0;
}

实验报告(三)

选择题。

  1. 设存在函数int max(int,int)返回两参数中较大值,若求22,59,70三者中最大值,下列表达式不正确的是__C.int m = max(22,59,70);___。
    原因:原函数形参只有两个,这里却传递了三个

填空题

  1. 在C++中,声明布尔类型变量所用的关键字是____bool____。
  2. C++语言中可以实现输出一个换行符并刷新流功能的操控符是___endl____。
  3. 在C++中使用流进行输入输出,其中用于标准错误输出的对象是___cerr和clog_____,屏幕输出的对象___cout_____。

简答题

  1. 对于一个频繁使用的短小函数,在C语言中应用什么实现,在C++中应用什么实现?
     使用内联函数实现
  2. 试给出一种方法,在不用第三方参数的情况下,交换两个参数的值。
    方法1:
int a = 1;
int b = 2;
a = a + b;
b = a - b;
a = a - b;

方法2:

int a = 1;
int b = 2;
a = a ^ b;
b = b ^ a;
a = a ^ b;

写出程序运行结果

1

#include <iostream>
#include <iomanip>
using namespace std;
void main()
{int a=29,b=100;
cout<<setw(3) <<a<<b<< endl;}
(指出a前面有几个空格)

答: 29100
 变量a=29前面有1个空格!setw()是给紧跟着后面的数据预定一个空间,如果该数据小于这个空间,在左边用空格补齐;setw()只对紧跟在他后面的数据有效
2

#include <iostream.h> 
void swap(int x,int y)
{ int t;
t=x; x=y; y=t; }
void main( )
{ int x=3, y=9;
swap(x,y);
cout<< x<< ‘,’<< y<<endl; }

答:3,9

3

#include <iostream.h>
#define LETTER 0
void main( )
{
    char c;
    do
    {
        cin.get(c);
        #if LETTER
            if (c>='a'&& c<='z')
                c=c-32;
        #else
            if (c>='A'&&c<='Z')
                c=c+32;
        #endif
        cout<<c;
    }
    while (c!='\n');
}

答:对输入的字符进行大小写转换处理,无输出内容

4

#include<iostream.h>
#include <math.h>
double area(double a, double b, double c)
{
    double s=(a+b+c)/2;
    return(sqrt(s*(s-a)*(s-b)*(s-c)));
}
void main( )
{
    float a,b,c;
    cin>>a>>b>>c;
    cout<<"the area is:"<< area(a,b,c) << '\n';
}

答:题意应该是用海伦公式求三角形的面积,但是该程序缺少对三角形三条边的和理性的判断,如:三角形的任意两边之和大于第三条边!输出结果不定!
5

#include <iostream.h>
#include <math.h>
#define S(a,b,c)  ((a+b+c)/2)
#define AREA(s, a, b, c)  sqrt(s*(s-a)*(s-b)*(s-c))
void main( )
{
    float a, b, c, area, s;
    cin>>a>>b>>c;
    s=S(a,b,c);
    area=AREA(s, a, b, c);
    cout<<"the area is:"<< area << '\n';
}

答:和上题一样,本题用宏定义的方法实现了上题函数定义的方法,题意应该是用海伦公式求三角形的面积,但是该程序缺少对三角形三条边的和理性的判断,如:三角形的任意两边之和大于第三条边!输出结果不定!

实验报告(四)

简答题

  1. C++函数中值的传递方式有哪几种?

    1. 值传递
    2. 指针传递
    3. 引用传递
    4. 全局变量传递
  2. 字符指针、浮点数指针、以及函数指针这三种类型的变量哪个占用的内存最大?
    答:一样大,占用都是4个字节

写出程序运行结果

1.

#include <iostream.h> 
void swap(int *px,int *py)
{ int t;
t=*px;*px=*py;*py=t; }
void main( )
{ int x=3,y=9,*p1,*p2;
p1=&x; p2=&y;
swap(p1,p2);
cout<< x<< ','<< y<<endl; } 

答:9,3使用指针地址传递,交换了两个变量的值
2

#include <iostream.h> 
#include<string>
void main()
{char *strp="Hello!";
cout<<strp<<endl;}

答:Hello!系统输出时,先输出strp所指向的第一个字符数据,然后使strp自动加1,使之指向下一个字符,然后再输出一个字符。直到遇到字符串结尾标志'\0'为止。注意,在内存中,字符串的最后被自动加了一个'\0',因此在输出时能确定字符串的终止位置。
3

#include <iostream.h>
#include <string>
void main( )
{ char a[20]="ABCD", b[10]="EFG";
int i, j;
i = strlen(a); 
for(j=0; b[j]!='\0'; i++,j++)
a[i]=b[j];
a[i]='\0';
cout << a << endl ;}

答:ABCDEFG,变量i与字符串a'\0'位置索引值相同,随后'\0'被覆盖
4

#include <iostream.h>
#include <string>
int my_strlen(char *s) // 自定义函数
{ int n ; 
for(n=0 ;*s!='\0' ;s++) n++ ; 
return(n); }
void main( )
{ char str[ ]="Hello!" ;
cout << *str << '\t'; 
cout << my_strlen(str) << '\t'; 
cout << *str << endl; }

答:H 6 H

#include <iostream.h>
void main(void)
{ 
    int a[10]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }, *p = a ; 
    int sum=0, i ;
   for( i=0; i<10; i++)
        sum = sum + *(p+i);  //   *(p+i)?p[i]?a[i]
   for( i=0; i<10; i++, p++) //  指针变量可进行自加、自减运算
       cout << *p<<endl;
   cout << "sum=" << sum << endl;
}

答:

1
2
3
4
5
6
7
8
9
10
sum=55

程序设计

1. 用返回指针值的函数实现求10个学生成绩中的最高分。

我的代码
#include <iostream>
#include <stdlib.h>
using namespace std;

int *maxScore(int scores[]){
    int index = 0;
    for (int i = 1; i < 10; i++)
        if (scores[index] < scores[i])
            index = i;
    return &scores[index];
}
int main(){
    int scores[] = {90,89,31,32,56,64,90,12,65,100};
    int *p = maxScore(scores);
    cout << *p << endl;
    system("pause");
    return 0;
}
实验标准代码
#include <stdio.h>
int *max(int x[],int n)
{
    int i,maxi=0;
    for(i=1;i<n;i++)                /* 查找最高分 */
        if(x[maxi]<x[i])maxi=i;        /* maxi存放最高分所对应元素的下标 */
    return &x[maxi];                /* 返回最高分所在元素的地址 */
}
int  main()
{
    int *p,a[10]={87,56,62,73,92,90,85,76,67,74};
    p=max(a,10);                    /* max函数返回最高分所在元素的地址 */
    printf("最高分=%d\n",*p);      /* 输出最高分 */
                return 0;
}

2. 编写一个字符串的复制函数。

我的代码
#include <iostream>
#include <stdlib.h>
using namespace std;
void strCopy(char *str, const char *source){
    while (*str++ = *source++);
}
int main(){
    char str1[100] = "hello world!";
    char str2[100] = "";
    strCopy(str2, str1);
    cout << str2 << endl;
    system("pause");
    return 0;
}

总结:
char str1[100] = "hello world!";char str2[100] = "";不要写成;char str1[] = "hello world!";char str2[] = "";,最好给一个比较大的容量,不然输出正确,但是程序终止时会崩溃!

实验标准代码
#include <stdio.h> 
void copy_string(char *to, char *from) 
{ 
/*将from所指的字符串中所有字符除'\0'外,全部复制到to所指的空间中*/
    while(*from!='\0') 
        *to++=*from++; 
    *to='\0';     /*在之前复制过来的字符后加'\0',表明to指向的是一个字符串*/
} 
int  main() 
{ 
    char a[]="I am a teacher.", b[]="You are a student."; 
    printf("Before copy:\n");
    printf("a: %s\nb: %s\n",a,b); 
    copy_string(b,a);
    printf("After copy: \n");
    printf("a: %s\nb: %s\n",a,b);  
                return 0;
}

实验报告(五)

写出程序运行结果

#include <iostream.h>
void  main(void)
{
   int a[10]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, t ;
   int *p1=a, *p2=a+9 ;
    while(p1<p2)
    {
            t = *p1; *p1 = *p2; *p2=t;
            p1++ ; p2 -- ; 
    }
    for(p1 = a; p1 < a+10; p1++)  cout << *p1 << endl ;
    cout << endl ;
}

答:实现数组反序排列

10
9
8
7
6
5
4
3
2
1
#include <iostream.h>
void   reverse(int b[ ], int n)
{  int  i, j, t; 
    i=0;  j=n-1; 
    while(i<j) {  t=b[i];  b[i]=b[j]; b[j]=t;
                          i++; j--; }
}
void  main(void)
{ int  a[10]={1,2,3,4,5,6,7,8,9,10},   i;
   reverse(a, 10);
   for(i=0; i<10; i++)  cout << a[i] << endl ;
   cout << endl ;
}

答:同上题一样,但是实现方法不一样

#include <iostream.h>
void   reverse(int b[ ], int n) // b是一个指针变量 
{  int  i, j, t; 
    i=0;  j=n-1; 
    while(i<j) 
   {   t=*(b+i); *(b+i)=*(b+j); *(b+j)=t;
        i++; j--;     // 原 t=b[i];  b[i]=b[j]; b[j]=t;
   }
}
void  main(void)
{ int  a[10]={1,2,3,4,5,6,7,8,9,10},   i;   
   reverse(a, 10);  
   for(i=0; i<10; i++)  cout << a[i] << endl ;
   cout << endl ;
}

答:同上两题一样,但是实现方式有细微差别,主要体现在指针的应用
4.

#include <iostream.h>
int fsum(int *array,int n)
{     int i,s=0;
      for(i=0;i<n;i++)
            s+=(*array++) ;
      return(s); 
 }
void main(void)
{     int a[15]={ 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 };
       int shead, stail;
       shead=fsum(a,10);  // 第 1 次调用
       stail=fsum(&a[5],10); // 第 2 次调用
       cout << shead <<',' << stail << endl;   
}

答:55,105,分别是对数组的前十个和后十个元素进行求和
5.

#include <iostream.h>
void max_min_value (int *array, int n, int *maxp, int *minp)
{    
      // maxp指向主函数max变量,minp指向主函数min变量
      int *p, *array_end;
      array_end = array + n ;
      *maxp=*minp=*array; 
      for(p=array+1; p < array_end; p++)
      {  
           if( *p>*maxp ) *maxp=*p;
          else if( *p<*minp ) *minp=*p; 
      }
}
void main(void)
{ 
      int i, number[10], *p = number, max, min;
      for(i=0; i<10; i++)
      cin >> *( p+i ) ;  // 输入数组元素值
      max_min_value( p, 10, &max, &min );
      for(i=0; i<10; i++)  
              cout << *( p+i ) << endl ;  // 输出数组元素值
       cout << "max value = " << max
               << "min value = " << min << endl ;
}

答:输出结果不定,程序功能是输入一个含有十个元素的整型数组,然后返回该整型数组的最大值和最小值

程序设计

1. 随机生成10个1~100之间的数存放在一维数组中,编写函数求其平均值以及最大的元素。

我的代码
#include <iostream>
#include <stdlib.h>
#include "time.h"
using namespace std;

// 求平均值
double aveVal(int *nums){
    int sum = 0;
    for (int i = 0; i < 10; i++)
    {
        sum += *(nums + i);
    }
    return sum / 10;
}
// 求最大元素
int maxElement(int *nums){
    int index = 0;
    for (int i = 1; i < 10; i++)
        if (*(nums + index) < *(nums + i)) 
            index = i;
    return *(nums + index);
}
int main()
{
    int nums[10];
    unsigned int seed = time(NULL);
    srand(seed);
    for (int i = 0; i < 10; i++)
    {
        nums[i] = rand() % 100 + 1;
        cout << nums[i] << endl;
    }
    cout << endl;
    cout << "平均值为:" << aveVal(nums) << endl;
    cout << "最大元素为:" << maxElement(nums) << endl;
    system("pause");
    return 0;
}
实验标准代码
#include <stdio.h>
#include <stdlib.h>
#define N 10
void fun(int *p,float *p1,int *p2)
{
    int sum,max,i; 
    sum=max=p[0];
    for(i=1;i<N;i++){
if (max<p[i])        /* 求最大值 */
max=p[i];
sum+=p[i];        /* 求和 */
    }
    *p1=1.0*sum/N;        /* *p1中存放平均值 */
    *p2=max;            /* *p2中存放最大值 */
}
int  main()
{
    int a[10],max,i;
    float aver;
    for(i=0;i<10;i++){
        a[i]= rand()%100+1;
        printf("%d ",a[i]);
    }
    fun(a,&aver,&max);    /* 函数调用 */
    printf("\naver=%.1f,max=%d\n",aver,max);
                return 0;
}

2.有5本书,要求按照字母顺序从小到大顺序输出书名。

我的代码
#include <iostream>
#include <string>
#include <stdlib.h>
#include <algorithm>
using namespace std;
int main()
{
    string books[5] = { "BASIC", "JAVA", "JSP", "C", "FOXPRO" };
    sort(books, books + 5);
    for (int i = 0; i < 5; i++)
    {
        cout << books[i] << endl;
    }
    system("pause");
    return 0;
}
实验标准代码
#include <stdio.h>
#include <string.h>
void sort(char *name[],int count)
{ 
    char *p;
    int i,j,min;                            
    for(i=0;i<count-1;i++){                /* 使用选择法排序 */
        min=i;                                 
        for(j=i+1;j<count;j++)
          if(strcmp(name[min],name[j])>0)
             min=j;                     
        if(min!=i)
        { p=name[i];
          name[i]=name[min];
          name[min]=p;
        }
    }
}
int main(){  
    char *name[5]={ "BASIC","JAVA","JSP","C","FOXPRO"};
    int i;
    sort(name,5); 
    for(i=0;i<5;i++)
        printf("%s\n",name[i]);  
                return 0;
}

实验报告(六)

写出程序运行结果

1

#include <iostream.h>
#include <string.h>
void main( )
{     char  a[20]="ABCD", b[10]="EFG";
       int  i, j;
       i = strlen(a);      // i是字符串a[ ]结尾‘\0’的下标
       for(j=0; b[j]!='\0'; i++,j++)
           a[i]=b[j];
       a[i]='\0';
       cout << a << endl;
}

答:ABCDEFG,变量i与字符串a'\0'位置索引值相同,随后'\0'被覆盖
2

#include <iostream.h>
void main( )
{     char  a[20]="ABCD", b[10]="EFG";
       char *pa=a, *pb=b;   //pa指向a[ ],pb指向b[ ]
       while(*pa!='\0') pa++;//循环结束后,pa指向a[]尾部的‘\0’
       while(*pb!='\0') 
        {    *pa=*pb;  pa++; pb++;    }
      *pa='\0';
      pa=a;
      cout << pa << endl ;
}

答:ABCDEFG,与上题一样,但是实现方式不一样,这题是将指针指向a'\0'位置,随后'\0'被覆盖
3

#include <iostream.h>
int my_strlen(char *s)    // 自定义函数
    {    int n ; 
         for(n=0 ;*s!='\0' ;s++) n++ ;
         return(n);
     }
    void main( )
    {    char str[ ]="Hello!" ;
          cout << *str << '\t';
          cout << my_strlen(str) << '\t';
          cout << *str << endl;
     }

答:H 6 H
4

#include <iostream.h>
   int my_strcmp(char *s,char *t) // 自定义函数 
   {     for( ; *s==*t; s++,t++)
             if(*s=='\0') return(0);
          return (*s-*t)>0 ? 1 : -1; 
    }
    void main( )
   {     char s1[ ]="Hello!";
          char *s2="Hello!";
          cout<< my_strcmp(s1, s2)<< '\t';
          cout<< my_strcmp("Hi", s2)<<endl; 
   }

答:0 1实现字符串比较
5

#include <iostream.h>
void main( )
{
    int a[3][4];
    int sum=0, i, j;
    for(i=0; i<3; i++)
        for(j=0; j<4; j++)
            cin>> *(a[i]+j);     //A
    for(i=0; i<3; i++)
        for(j=0; j<4; j++)
            sum += *(*(a+i)+j);  //B 
    cout << sum << endl;
}

答:主要考察通过两种不同的方式输入/出二维数组的值,并对其求和
6

#include <iostream.h>
int total( int(*p)[4], int n )  //  A
{
    int i, j, sum=0;
    for( i=0; i<n; i++)
        for( j=0; j<4; j++)
            sum += *(*(p+i)+j) ;
    return sum;
}
void main(void)
{     
    int a[3][4], sum, i, j;    
    for(i=0; i<3; i++)
        for(j=0; j<4; j++)
            cin>> *(a[i]+j); 
    sum = total( a, 3 );
    cout << sum << endl;
}
//改写total()
int total(int(*p)[4], int n)
{
    int i, j, sum=0 ;
    for( i=0; i<n; i++, p++ )    //A
        for( j=0; j<4; j++)
            sum += *( *p + j );  //B
    return sum;
}

答:所含盲点:

  1. int(*p)[4];------ptr为指向含4个元素的一维整形数组的指针变量(是指针)
  2. int *p[4];-------定义指针数组p,它由4个指向整型数据的指针元素组成(是数组)
  3. int()[4];--------实际上可以看作是一种数据类型。也就是第一个(int(p)[4];)中定义的p的数据类型

7

#include <iostream.h> 
#include <iomanip.h> 
void main(void)
{
    int a[3][4]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}, *p ;
    for(p=a[0]; p<a[0]+12; p++)               //A
    {
        if((p-a[0])%4==0) cout << endl ;      //B
        cout << setw(4) << *p ;
    }
    cout << endl;
}

答:

   1   2   3   4
   5   6   7   8
   9  10  11  12

8

#include <iostream.h>
void main(void)
{
    int a[3][4]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
    int *p, i, j;
    p=a[0];
    cin >> i >> j; 
    cout<< "a[" << i << "][" << j<< "]=" << *(p+i*4+j) << endl; 
}

答:指定输出i行,j列元素
9

#include <iostream.h>
void main( )
{
    float a[5]={2, 4, 6, 8, 10};
    float *p[5]={ &a[0], &a[1], &a[2], &a[3], &a[4]};  //A
    int i;
    for(i=0; i<5; i++) cout << *p[i] << '\t';
    cout << '\n';
}

答:定义了一个含有5个元素的指针变量来保存另一个数组,并对其值进行打印
10

#include <iostream.h>
void main(void)
{
    int a[2][3]={{1, 2, 3}, {4, 5, 6}};
    int *pa[ ]={a[0], a[1]}; //通过初始化的方式给指针数组赋初值。
    int i , j;
    for(i=0; i<2; i++)
    {
        for(j=0; j<3; j++)
            cout << *(pa[i]+j) << '\t';
        cout << '\n';
    }
}

答:以矩阵的形式打印二维数组
11

#include <iostream.h>
#include <string.h>
void main( )
{  
    char *name[ ]={"George", "Mary", "Susan", "Tom", "Davis"};
    char *ptr; 
    int i, j, k, n=5;
    for(i=0; i<n-1; i++)
    { 
        k=i;
        for(j=i+1; j<n; j++)
            if( strcmp(name[k], name[j])>0 ) //字符串比较,
                k=j;          //记住最小字符串指针的下标。
        if(k!=i)
        { ptr=name[i]; name[i]=name[k]; name[k]=ptr; } //交换指针数组元素值
    }
    for(i=0; i<n; i++) //输出结果
        cout << name[i] <<'\t';
    cout<<endl;
}

答:Davis George Mary Susan Tom对字符数组进行排序
12

#include <iostream.h>
#include <string.h>
void main( ) 
{
    void sort(char *[ ], int), print(char *[ ], int); // 函数原型说明,因为函数定义在后
    char *name[ ] = {"George", "Mary", "Susan", "Tom", "Davis"};
    int n=5 ;
    sort( name, n);          // 调用函数sort,注意实参 
    print( name, n);         // 调用函数sort,注意实参
}
void sort(char *name[ ], int n)    //函数定义,注意形参的写法
{
    char *ptr; int i, j, k;
    for(i=0; i<n-1; i++)
    {
        k=i;
        for(j=i+1; j<n; j++)
            if( strcmp(name[k], name[j])>0 ) k=j;
        if(k!=i)
        {    ptr=name[i]; name[i]=name[k]; name[k]=ptr;    }
    }
}
void  print(char *name[ ], int n)    // 函数定义,注意形参的写法
{
    for(int i=0; i<n; i++)
        cout <<name[i] << endl;
}

答:

Davis
George
Mary
Susan
Tom

13

#include<iostream.h>
void main(int argc, char *argv[ ])
{
    cout<<"argc="<<argc<<endl;
    cout <<"Command name=" << argv[0] << endl;
    for(int i=1; i<argc; i++)
        cout<<argv[i]<<endl;
}

答:

argc=1
Command name=C:\Users\xzb\Desktop\关于C++\C++复习\复习\Debug\复习.exe

14

#include<iostream.h>
void  main( )
{
    char **p;
    char *s[ ]={ "up", "down", "left", "right" };
    int i;
    p=s;
    for( i=0; i<4; i++ )
        cout << *p++ <<'\t';    // A
    cout<<endl;
}

答:up down left right

15

#include<iostream.h>
void main( )
{
    int max(int, int), min(int, int);// 函数原型声明
    int (*fp)(int, int);         // 定义函数指针 fp
    int a, b, c, d;
    cin>>a>>b;
    fp = max;         // fp 指向 max( ) 函数
    c = fp(a, b);     // 通过 fp 调用 max( ) 函数
    fp = min;        // fp 指向 min( ) 函数
    d = (*fp)(a, b);    // 通过 fp 调用 min( )函数
    cout<<"max="<<c<<'\t'<<"min="<<d<< endl; 
}
int max(int x, int y)  { return(x>y?x:y); }  
int min(int x, int y)  { return(x<y?x:y); }  

答:函数指针的应用
16

#include  <iostream.h>
char *find(char *str, char ch)  // 返回值类型为 char * 
{  
    while(*str!='\0') 
        if(*str==ch) return(str);
        else  str++;
    return(NULL);  //若找不到,返回空指针
}
void main( ) 
{
    char  s[ ]="warrior";
    char  *p;
    p = find(s, 'r');  if(p) cout << p<< endl;  // 输出 rrior
    p = find(s, 'i');  if(p) cout << p<< endl;  // 输出 ior
    p = find(s, 'b');  if(p) cout << p<< endl;  // 无输出
}

答:

rrior
ior

17

#include  <iostream.h>
void my_strcpy(char * dest, const char *source)  // A 注意第二个参数的定义
{  
    while( *dest++ = *source ++);  
}
void main( )
{
    char a[20] = "How are you!"; 
    char b[20];
    my_strcpy(b, a);
    cout << b << endl;
}

答:How are you!

程序设计

1.字符串拷贝函数,比较以下几个函数的异同。

 #include <iostream.h>
void copy_string(char to[ ], char from[ ])
{
    int i = 0;

    while(from[i] != '\0') 
    { 
        to[i] = from[i]; 
        i++;
    }
    to[i]='\0';  
}

void copy_string(char to[ ], char from[ ])
{
    int i = 0;

    while((to[i] = from[i]) != '\0') i++;  
}

void copy_string(char *to, char *from)
{
    while( (*to = *from) != '\0') 
    {   from++; to++; }  
}

void copy_string(char *to, char *from)
{
    while((*to++ = *from++)!='\0');  
}

void copy_string(char *to, char *from)
{ 
    while(*to++ = *from++);  
}
//以上五个函数的功能是一样的,可以用下述主函数调用。

void main( )
{
    char s1[20], s2[20];
    
    cin>>s2;
    copy_string(s1, s2);
    cout<<s1<<endl;
}

答:的优先级比++要高。其次,在进行赋值运算的时候是从右向左进行的,故应该是行执行from(即取值),将from的值付给to,然后from++,to++;最后当*form==‘0’时,推出循环。

实验报告(七)

程序设计

1.对运算符“+”实行重载,使之能用于复数相加。

#include <iostream>
using namespace std;
class Complex
 {public:
   Complex(){real=0;imag=0;}
   Complex(double r,double i){real=r;imag=i;}
   Complex operator + (Complex &c2);
   void display();
  private:
   double real;
   double imag;
 };
Complex Complex::operator + (Complex &c2)
{Complex c;
 c.real=real+c2.real;
 c.imag=imag+c2.imag;
return c;}
void Complex::display()
{cout<<"("<<real<<","<<imag<<"i)"<<endl;}
int main()
{Complex c1(3,4),c2(5,-10),c3;
 c3=c1+c2;
 cout<<"c1=";c1.display();
 cout<<"c2=";c2.display();
 cout<<"c1+c2=";c3.display();
 return 0;
}
#include <iostream>
using namespace std;
class Complex
 {public:
   Complex(){real=0;imag=0;}
   Complex(double r,double i){real=r;imag=i;}
   Complex operator + (Complex &c2);
   void display();
  private:
   double real;
   double imag;
 };
Complex Complex::operator + (Complex &c2)
 {return Complex(real+c2.real,imag+c2.imag);}
   
void Complex::display()
{cout<<"("<<real<<","<<imag<<"i)"<<endl;}
int main()
{Complex c1(3,4),c2(5,-10),c3;
 c3=c1+c2;
 cout<<"c1="; c1.display();
 cout<<"c2="; c2.display();
 cout<<"c1+c2="; c3.display();
 return 0;
}

3.将加法运算符重载为适用于复数加法,重载函数作为类的友元函数。

#include <iostream.h>    
class Complex
     {public:
       Complex () {real=0;imag=0;}
       Complex (double r) {real=r;imag=0;}
       Complex (double r,double i) {real=r;imag=i;}
       friend Complex operator+ (Complex &c1, Complex &c2);
       void display();
      private:
       double real;
       double imag;
     };
Complex operator+ (Complex &c1, Complex &c2)
     {  return Complex(c1.real+c2.real, c1.imag+c2.imag) ; } // 显式调用构造函数
    void Complex::display()
    {cout<<"("<<real<<","<<imag<<"i)"<<endl;}
int main()
    {   Complex c1(3,4),c2(5,-10),c3;
        c3=c1+c2;
        cout<<"c1="; c1.display();
        cout<<"c2="; c2.display();
        cout<<"c1+c2="; c3.display();
        return 0;
    }

4.声明一个字符串类string,重载运算符“”、“”、“”,使得它们能用于两个字符串的等于、小于和大于的比较运算。

#include <iostream>
#include <cstring>
using namespace std;
class String
 {public:
   String(){p=NULL;}
   String(char *str);
   friend bool operator>(String &string1,String &string2);
   friend bool operator<(String &string1,String &string2);
   friend bool operator==(String &string1,String &string2);
  void display();
  private:
   char *p;
 };
String::String(char *str)
{p=str;
}
void String::display()
 {cout<<p;}
bool operator>(String &string1,String &string2)
{if(strcmp(string1.p,string2.p)>0)
   return true;
 else
   return false;
}
bool operator<(String &string1,String &string2)
{if(strcmp(string1.p,string2.p)<0)
   return true;
 else
   return false;
}
bool operator==(String &string1,String &string2)
{if(strcmp(string1.p,string2.p)==0)
   return true;
 else
   return false;
}
void compare(String &string1,String &string2)
{if(operator>(string1,string2)==1)
  {string1.display();cout<<">";string2.display();}
 else
  if(operator<(string1,string2)==1)
   {string1.display();cout<<"<";string2.display();}
 else
  if(operator==(string1,string2)==1)
   {string1.display();cout<<"=";string2.display();}
 cout<<endl;
}
int main()
{String string1("Hello"),string2("Book"),string3("Computer"),string4("Hello");
 compare(string1,string2);
 compare(string2,string3);
 compare(string1,string4);
 return 0;
}

5.重载前置和后置运算符,实现time类中分钟和秒的输出。

#include <iostream>
using namespace std;
class Time
{public:
   Time(){minute=0;sec=0;}
   Time(int m,int s):minute(m),sec(s){}
   Time operator++();
   Time operator++(int);
   void display(){cout<<minute<<":"<<sec<<endl;}
  private:
   int minute;
   int sec;
 };
Time Time::operator++()
{if(++sec>=60)
  {sec-=60;
   ++minute;}
 return *this;
}
Time Time::operator++(int)
{Time temp(*this);
 sec++;
 if(sec>=60)
  {sec-=60;
   ++minute;}
 return temp;
}
int main()
{Time time1(34,59),time2;
 cout<<" time1 : ";
 time1.display();
 ++time1;
 cout<<"++time1: ";
 time1.display();
 time2=time1++;
 cout<<"time1++: ";
 time1.display();
 cout<<" time2 : ";
 time2.display();
 return 0;
}
  1. 设计程序实现访问公有基类的成员:(1)基 类 Student,私有数据成员 num,name,sex;
    公有成员函数get_value()、display()分别输入、输出基类的数据;(2)公有派生类Student1,新

增私有数据成员age,addr;新增公有成员函数get_value_1()、display_1()分别输入、输出派生
类的数据;(3)主函数里声明派生类对象stud,调用基类和派生类的公有成员函数输入5个数据,
调用基类和派生类的公有成员函数输出5个数据。

#include <iostream> 
#include <string> 
using namespace std; 
class Student 
{public: 
  void get_value() 
   {cin>>num>>name>>sex;} 
  void display( ) 
    {cout<<"num: "<<num<<endl; 
     cout<<"name: "<<name<<endl; 
     cout<<"sex: "<<sex<<endl;} 
  private : 
   int num; 
   string name; 
   char sex; 
}; 
class Student1: public Student 
  {public: 
   void get_value_1() 
    {cin>>age>>addr;} 
   void display_1() 
    {   
       cout<<"age: "<<age<<endl;          //引用派生类的私有成员,正确 
       cout<<"address: "<<addr<<endl;}    //引用派生类的私有成员,正确 
  private: 
       int age; 
       string addr; 
  }; 
int main() 
  {Student1 stud1; 
  stud1.get_value(); 
  stud1.get_value_1(); 
  stud1.display(); 
  stud1.display_1(); 
  return 0; 
}

实验报告(八)

1. 关于API

 应用程序也是以函数调用的方式来通知操作系统执行相应的功能的。操作系统所能够完成的每一个特殊功能通常都有一个函数与其对应,也就是说,操作系统把它所能够完成的功能以函数的形式提供给应用程序使用,应用程序对这些函数的调用就叫做系统调用,这些函数的集合就是Windows操作系统提供给应用程序编程的接口(Application Programming Interface),简称Windows API。

2.关于消息及消息队列

 操作系统是怎样将感知到的事件传递给应用程序的呢?这是通过消息机制(Message)来实现的。操作系统将每个事件都包装成一个称为消息的结构体MSG来传递给应用程序,参看MSDN。

  • MSG结构定义如下:
typedef struct tagMSG {       
        HWND   hwnd;      
        UINT   message;
        WPARAM wParam;
        LPARAM lParam;
        DWORD  time;
        POINT  pt;
} MSG; 

3.关于句柄

  • 句柄(HANDLE),资源的标识。
  • 操作系统要管理和操作这些资源,都是通过句柄来找到对应的资源。按资源的类型,又可将句柄细分成图标句柄(HICON),光标句柄(HCURSOR),窗口句柄(HWND),应用程序实例句柄(HINSTANCE)等等各种类型的句柄。操作系统给每一个窗口指定的一个唯一的标识号即窗口句柄。
  • WinMain函数
// Windows程序的入口函数
int WINAPI WinMain(
  HINSTANCE hInstance,      // handle to current instance
  HINSTANCE hPrevInstance,  // handle to previous instance
  LPSTR lpCmdLine,          // command line
  int nCmdShow              // show state
);

4.窗口的创建

 创建一个完整的窗口需要经过下面四个操作步骤:

  1. 设计一个窗口类;
  2. 注册窗口类;
  3. 创建窗口;
  4. 显示及更新窗口。

5.设计窗口类

typedef struct _WNDCLASS { 
   UINT        style; 
   WNDPROC    lpfnWndProc; 
   int         cbClsExtra; 
   int         cbWndExtra; 
   HANDLE     hInstance; 
   HICON       hIcon; 
   HCURSOR     hCursor; 
   HBRUSH      hbrBackground; 
   LPCTSTR     lpszMenuName; 
   LPCTSTR     lpszClassName;  
} WNDCLASS; 

6.窗口类的类型

 在我们的程序中经常要用到一类变量,这个变量里的每一位(bit)都对应某一种特性。当该变量的某位为1时,表示有该位对应的那种特性,当该位为0时,即没有该位所对应的特性。当变量中的某几位同时为1时,就表示同时具有几种特性的组合。一个变量中的哪一位代表哪种意义,不容易记忆,所以我们经常根据特征的英文拼写的大写去定义一些宏,该宏所对应的数值中仅有与该特征相对应的那一位(bit)为1,其余的bit都为0。我们使用goto definition就能发现CS_VREDRAW=0x0001,CS_HREDRAW=0x0002,CS_DBLCLKS =0x0008,CS_NOCLOSE=0x0200。他们的共同点就是只有一位为1,其余位都为0。如果我们希望某一变量的数值既有CS_VREDRAW特性,又有CS_HREDRAW特性,我们只需使用二进制OR(|)操作符将他们进行或运算相组合,如style=CS_VREDRAW | CS_HREDRAW | CS_NOCLOSE。如果我们希望在某一变量原有的几个特征上去掉其中一个特征,用取反(~)之后再进行与(&)运算,就能够实现,如在刚才的style的基础上去掉CS_NOCLOSE特征,可以用style & ~CS_NOCLOSE实现。

7.窗口过程函数

 第二个成员变量lpfnWndProc指定了这一类型窗口的过程函数,也称回调函数。回调函数的原理是这样的,当应用程序收到给某一窗口的消息时(还记得前面讲过的消息通常与窗口相关的吗?),就应该调用某一函数来处理这条消息。这一调用过程不用应用程序自己来实施,而由操作系统来完成,但是,回调函数本身的代码必须由应用程序自己完成。对于一条消息,操作系统到底调用应用程序中的哪个函数(回调函数)来处理呢?操作系统调用的就是接受消息的窗口所属的类型中的lpfnWndProc成员指定的函数。每一种不同类型的窗口都有自己专用的回调函数,该函数就是通过lpfnWndProc成员指定的。
举例:汽车厂家生产汽车好比应用程序创建窗口,用户使用汽车好比操作系统管理窗口,某种汽车在销售前就指定好了修理站(类似回调函数),当用户的汽车出现故障后(类似窗口收到消息),汽车用户(类似操作系统)自己直接找到修理站去修理,不用厂家(类似应用程序)亲自将车送到修理站去修理,但修理站还得由厂家事先建造好。

8.设计一个简单的 windows程序。

我的代码

#include <Windows.h>
LRESULT CALLBACK DealMessage(HWND hwnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam
    );
int WINAPI WinMain(HINSTANCE hInstance,            //应用程序实例
    HINSTANCE hPrevInstance,                //上一个应用程序实例
    LPSTR lpCmdLine,                        //命令行参数
    int nCmdShow                            // 窗口显示样式,最大化,最小化
    )
{
    /*
    1、定义入口函数 WinMain()
    2、创建一个窗口
        1、设计窗口类 WNDCLASS
        2、注册窗口类
        3、创建窗口类
        4、显示和更新窗口
    3、消息循环
    4、窗口过程函数
    */
    //1、设计窗口类 WNDCLASS
    WNDCLASS wc;
    wc.cbClsExtra = 0;        //类的附加信息
    wc.cbWndExtra = 0;        //窗口附加信息
                                //获取系统默认的白色画刷
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);        //背景色必须要写

    /*
    wc.hCursor = NULL;        使用默认的
    */

    wc.hCursor = LoadCursor(NULL, IDC_HELP);        //加载系统默认光标
    /*
    wc.hIcon = NULL;    默认的
    */

    wc.hIcon = LoadIcon(NULL, IDI_WARNING);                //加载系统默认图标
    wc.hInstance = hInstance;
    wc.lpfnWndProc = DealMessage;                       //窗口过程函数的名字,消息处理函数

    wc.lpszClassName = TEXT("abc");            //类的名字
    wc.lpszMenuName = NULL;                //菜单名字
    wc.style = nCmdShow;                //显示风格


    //2、注册窗口类,告诉系统窗口过程函数入口地址
    RegisterClass(&wc);

    //创建窗口类
    HWND hWnd = CreateWindow(TEXT("abc"), TEXT("hello, windows"), WS_EX_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
        NULL, NULL, hInstance, NULL);

    //显示和更新窗口
    ShowWindow(hWnd, SW_SHOWNORMAL);
    UpdateWindow(hWnd);
    //消息循环
    MSG msg;
    //如果接收到 WM_QUIT 返回0, 退出
    //如果出错,返回-1,不退出
    while (GetMessage(&msg, NULL, 0, 0))
    {
        //翻译工作
        //虚拟按键转换为标准字符 WM_CHAR
        TranslateMessage(&msg);

        //给操作系统分发消息
        DispatchMessage(&msg);
    }
    return msg.wParam;
}
LRESULT CALLBACK DealMessage(HWND hWnd,
    UINT uMsg,
    WPARAM wParam,
    LPARAM lParam
    )
{
    switch (uMsg)
    {
    case WM_LBUTTONDOWN:
        MessageBox(hWnd, TEXT("ABC"), TEXT("鼠标左键按下"), MB_OK);
        break;

    case WM_DESTROY:
        PostQuitMessage(2);
        break;

    case WM_PAINT:
    {
                     PAINTSTRUCT ps;
                     HDC dc = BeginPaint(hWnd, &ps);
                     TCHAR *p = L"许增宝";
                     TextOutW(dc, 30, 30, p, wcslen(p));

                     EndPaint(hWnd, &ps);
                     break;
    }
    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
        break;
    }

    return 0;
}

实验标准代码

#include <windows.h>
#include <stdio.h>
LRESULT CALLBACK WinSunProc(
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
);
int WINAPI WinMain(
  HINSTANCE hInstance,      // handle to current instance
  HINSTANCE hPrevInstance,  // handle to previous instance
  LPSTR lpCmdLine,          // command line
  int nCmdShow              // show state
)
{
    WNDCLASS wndcls;
    wndcls.cbClsExtra=0;
    wndcls.cbWndExtra=0;
    wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
    wndcls.hCursor=LoadCursor(NULL,IDC_CROSS);
    wndcls.hIcon=LoadIcon(NULL,IDI_ERROR);
    wndcls.hInstance=hInstance;
    wndcls.lpfnWndProc=WinSunProc;
    wndcls.lpszClassName="Weixin2003";
    wndcls.lpszMenuName=NULL;
    wndcls.style=CS_HREDRAW | CS_VREDRAW;
    RegisterClass(&wndcls);
    HWND hwnd;
    hwnd=CreateWindow("Weixin2003","北京维新科学技术培训中心",WS_OVERLAPPEDWINDOW,
        0,0,600,400,NULL,NULL,hInstance,NULL);
    ShowWindow(hwnd,SW_SHOWNORMAL);
    UpdateWindow(hwnd);
    MSG msg;
    while(GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}
LRESULT CALLBACK WinSunProc(
  HWND hwnd,      // handle to window
  UINT uMsg,      // message identifier
  WPARAM wParam,  // first message parameter
  LPARAM lParam   // second message parameter
)
{
    switch(uMsg)
    {
    case WM_CHAR:
        char szChar[20];
        sprintf(szChar,"char is %d",wParam);
        MessageBox(hwnd,szChar,"weixin",0);
        break;
    case WM_LBUTTONDOWN:
        MessageBox(hwnd,"mouse clicked","weixin",0);
        HDC hdc;
        hdc=GetDC(hwnd);
        TextOut(hdc,0,50,"计算机编程语言培训",strlen("计算机编程语言培训"));
        ReleaseDC(hwnd,hdc);
        break;
    case WM_PAINT:
        HDC hDC;
        PAINTSTRUCT ps;
        hDC=BeginPaint(hwnd,&ps);
        TextOut(hDC,0,0,"维新培训",strlen("维新培训"));
        EndPaint(hwnd,&ps);
        break;
    case WM_CLOSE:
        if(IDYES==MessageBox(hwnd,"是否真的结束?","weixin",MB_YESNO))
        {
            DestroyWindow(hwnd);
        }
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hwnd,uMsg,wParam,lParam);
    }
    return 0;
}
最后修改:2019 年 05 月 30 日 02 : 02 AM

此处评论已关闭

4 条评论

  1. 你大爷永远是你大爷

    哇咔咔,老师给的实验太多了

    1. One 许增宝
      1. 你大爷永远是你大爷
        @One 许增宝

        哇咔咔,我还在抄实验报告

        1. reacroy
          @你大爷永远是你大爷

          我也在抄,抄将近6个小时了,太多了