c++第一二章

目录

一、非编程题

一)、判断

二)、选择

三)、复习的小知识:

二、编程题

一)、6-3 逆序字符串

二)、 6-8 工作备忘录的生成(链表)

函数接口定义:

裁判测试程序样例:

输入样例:

输出样例:

三)、7-1 查找单价最高和最低的书籍

输入样例:

输出样例:


一、非编程题

一)、判断 

1.可以将结构体变量作为一个整体进行输入或输出。

F,不能用对象名进行整体的输入输出,可以通过运算符重载来实现,第四章

4.可以通过下标随机访问向量vector中的元素。

T,[n](下标运算符)或者at(n),第八章

9.形参 int fun(int a=1,int b,int c=2)是否合法?
不合法,指定了默认值的形参后,其右边不能出现没有默认值的形参,即默认值集中在形参列表的右边。同时,不能指定引用参数的默认值(int & m = 4不可以),引用参数不能用常量赋值

10.判断数组声明及初始化语句 char str[]={'H','e','l','l','o'};是否正确。

T,数组初始化的方法有两种,一种后面加‘\0',一种不加,都正确,只是前者的长度比后者多一个。

12.两个以上的函数,具有相同的函数名,且形参的个数或形参的类型不同,或返回的数据类型不同,则称之为函数的重载。

F,返回值类型不同,不能作为重载的依据

*内联函数提高效率,但目标代码的长度减少。F

二)、选择

1.命名空间应用于:

A.在类外定义类的成员函数//其实是在类内定义成员函数; 

B.避免各个不同函数、变量等的名称冲突; 

C.提高代码的执行速度//相反,这会降低运行速率,若是普通变量,只需要转到变量的地址中,而调用命名空间中的变量需要先转到命名空间,从命名空间中获取变量的地址

D.以上答案都正确

2.逻辑运算符两侧运算对象的数据类型( )。

A.只能是 0 或 1

B.只能是 0 或非 0 正数

C.只能是整型或字符型的数据;  

D.可以是任何类型的数据。

//原则为:非0即1,基本的操作符有:“非”(¬)、“与”(∧)、“或”(∨)、“条件”(→)以及“双条件”(↔)。注意,符号“与”(∧)和交集(∩),“或”(∨)和并集(∪)的相似性。这不是巧合:交集的定义使用“与”,并集的定义是用“或”

  3.设有程序段    则下面描述中正确的是( )。

int m=20; while (m=0) m=m++;

A.while 循环执行 10 次

B.循环是无限循环

C.循环体语句一次也不执行

D.循环体语句执行一次。

在c++中=也为赋值操作符,若m被赋值为非零值,则进行无限次循环,m被赋值为零,布尔类型为false不进行循环;==为判断,

  12.设int x;,则经过()后,语句*px=0可将x值置为0。//指向的不能是常量

A.int * px;//没有把px指向x

B.int const * px=&x;//此时*p=0;会显示编译错误,但x = 0; 可以修改x的值

 C.int * const px=&x;//常量指针

//const修饰px为常指针,px不可变,px不能指向其他变量,px指向的x可变

D.const int * px=&x;//指向常量的指针

//B和D中const修饰指向的对象,即常变量px可变,px指向的x不可变;又想到了一个问题,此时px指向x,x不可变(可以直接修改x的值,但不可以通过*p修改x的值),若px不再指向x,那x还可变吗:(再复习时一看,问这个问题应该是指针还没掌握好)可以变,const int const*p = &x;指向常量的常指针

常量指针、指向常量的指针和指向常量的常指针三者之间的区别_夏梦星晨的博客-CSDN博客_指向常量的常量指针

4.如果要求在if后一对括号中的表达式在表示a 不等于 0 的时候的值为“真”,则能正确表示这一关系的表达式为( )。A.a<>0B.!a //若a是零,!a是非零值,若a是非零值,!a是零;C.a=0D.a//若a为布尔类型,a为非零值时结果是true,a为零时结果是faole

	int a = 0;
	if(!a)
	{
		cout <<"为真";
	}
	if(a)
	{
		cout<<"true";
	 } 
//输出为真

17.以下程序的输出结果是( )。

int main( )

{ char a[10]={'1', '2', '3', '4', '5', '6', '7', '8', '9', 0}, *p;

int i;

i=8;

p=a+i;

cout<<p-3; }

A.6;B.6789;C.' 6';D.789;//因为最后为'\0',因此此处数字数组可以当做字符串使用,若是输出*(p-3),最后输出6,此处类似于输出字符串的首地址,输出字符串的首地址就会输出全部字符串;

20.关于C++与C 语言关系的描述中,( )是错误的。A.C 语言是C++语言的一个子集;  B.C 语言与C++语言是兼容的;  C.C++语言对C 语言进行了一些改进;  D.C++语言和C 语言都是面向对象的//c是面向过程的语言

6.以下程序存在的问题是:

void fun()
{
 int *num1, *num2;
 num1 = new int[10];
 num2 = new int[20];
 num1[0] = 100;
 num2[0] = 300;
 num1 = num2;
 delete [] num1;
}

A.num2不能给num1赋值;//可以,都是变量,数据类型相同

B.num2最初指向的空间没有释放;

C.num1最初指向的空间没有释放;

D.程序没有问题//把num2的地址赋值给num1,在撤销num1时,相当于撤销num1当时指向的地址,相当于把num2最初指向的地址删了,nu1最初指向的地址的内存还留着

  8.下列选项哪一个是正确的?

A.char *p=new int; p='a'; delete p; 

 B.int *p=new int[25]; p[10]=100; delete p; 

 C.char *p=new char[10]; p[0]='k'; delete [ ] p;   

D.char *p=new char; p[0]='k'; delete p;  //delete p;只对p[0]析构(只释放了数组名对应的class,即下标为0的class,其他class会变成垃圾class继续留在内存中)([]是告诉编译器指针(此处是p)指向的是数组,因此在释放指针所指向的内存区块时,必须要查询和使用该数组的维度信息,这样才能释放指针指向数组的内存资源,c++出于效率的考虑,仅在有[]时才会查询维度信息,否则编译器会认为指针指向的时单个内存资源《C++ Common Knowledge》-条款36-page93。)(zuto_ptr<typename>:不要把他作为数组,即在使用auto_ptr不能有如下操作:char* _parray = new char[100];auto_ptr<char>_parray(_p););delepe []p;会对数组中所有的class析构;

   45.以下初始化语句正确的是( )。  

A.string * p="this" ; 

 B.string p[ ]="that";   //虽然编译没有问题,但输出异常

C.string p[ ]={"What","this"};  //  

D.char * p={ "Please" } ;  //不能把const char *赋值给 char *;

  10.在C++中,函数原型不能标识()。A.函数的返回类型;B.函数参数的个数;C.函数参数类型;D.函数的功能//函数原型是函数声明,也叫引用说明,目的是先调用函数,后声明函数

  11.执行以下的程序片段,将输出几个数字?

for(i=0;i<3;i++);

       cout<<i;

A.0;  B.1;  C.2 ;   D.3;//又忘记了for后面的";",(((φ(◎ロ◎;)φ)))

22.若有以下调用语句,则不正确的fun( )函数的首部是:

int main( ) 
{
 int a[50]={1},n=20;
 fun(n,&a[9]);
 …
 };

 A.void fun(int m,int x[ ]); 

 B.void fun(int s,int h[41]);

 C.void fun(int p,int *s);

 D.void fun(int n,int a) ;  //第一形参没问题 第二个形参为地址,此处是变量

23.编写C++程序一般需经过的几个步骤依次是();

A.编辑、调试、编译、连接;

B.编辑、编译、连接、运行;//调试包含在编辑中

C.编译、调试、编辑、连接;

D.编译、编辑、连接、运行 //看课本看课本

26. 下列程序的执行结果为

#include<iostream>
using namespace std;

int main() {
    int a = 3, b = 0;
    int * p = &a;
    b = +a++;
    cout << *p << ", " << b << endl;
    return 0;
}

A.3, 4;  B.4, 3;   C.3, 3;   D.4, 4  //+a++:+a是正a,a++ = 3,++a = 4;

 15.下列关于引用的说法,错误的是____。A.引用在定义时必须初始化B.引用在初始化时不能绑定常量值C.引用初始化后,可以通过更变来引用其他变量D.数组不能定义引用//又粗心了(lll¬ω¬)

16.若有下面的语句:

vector<int> v;
for (int i = 0; i < 4; i++)
    v.push_back(i + 1);
cout << v.size() << endl;

则执行后程序的输出结果是A.1;   B.2;   C.3;   D.4//vector可以改变大小的数组

 37.关于delete运算符的下列描述中,()是错误的。A.它必须用于new返回的指针;B.使用它删除对象时要调用析构函数;C.对一个指针可以使用多次该运算符;//D.指针名前只有一对方括号符号,不管所删除数组的维数。

 18.下面关于new运算符的描述中错误的是( )A.使用new创建对象时必须定义初始值;//这肯定错啊,在课本37页,什么都不加,申请的内存空间没有指定初始值,加()在括号中不能指定任何初始值,编译器自动初始化为零,加{}使用列表初始化定义初始值;B.使用new创建对象时会调用类的构造函数;C.new可以用来动态创建对象和对象数组;D.使用new创建的对象可以使用delete删除;  //new用于动态分配内存,不需要显示调用构造函数,它会自己调用

①动态分配二维数组:
#define hang 4
#define lie 5
int **str1 = new int *[hang];
for(int  i = 0; i < hang; i++)
{
  str1[i] = new int [lie];
}
②动态分配三维数组
#define m 3
double (*str2) = new (double[m][3][3]);

20.

int x = 1;
int y = 2;
int z = 3;
cout<<(x,y,z)<<(x,y,z)<<(x,y,z);

为什么会输出三个3?好像是输出三个数中的最大值

三)、复习的小知识:

1.cout << "Error " "53";原来这样的输出和cout<<"Error 53",没什么区别

二、编程题

一)、6-3 逆序字符串

 设计一个void类型的函数reverse_string,其功能是将一个给定的字符串逆序。例如,给定字符串为“hello”,逆序后为“olleh”。

#include <iostream>
#include <string>
using namespace std;

/* 你的代码将嵌在这里 */

int main(int argc, char const *argv[])
{
    string str;
    getline(cin, str);        //输入字符串
    reverse_string(str);     //逆序字符串str
    cout << str << endl;    //输出逆序后的字符串
    return 0;
}

第一次错误:


void reverse_string(*str)
{
	char *p;
	p = str;
	while(*p)
	{
		p++;
	}
	for(int i = 0; *p;i++)
	{
		str[i] = *p;
		p--;
	}
	return 0;
}

显示错误:编译错误

1.应该用&取地址运算符,而不是*取值运算符,并标明类型string,第二次修改p的赋值方式;

//并不是,&str是引用,*p是char类型的,①如果是string的指针,char*无法和string进行赋值运算;②如果是string的引用,如果按照第一次编辑中p=str,复制运算符左边是char*,右边是string,明显错误,需进行强制类型转换,或换种复制方式。

2.第二次与第一次相比还互换了for中的p--和i++的位置,意义不大

第二次错误:输入与输出一样


void reverse_string(string &str)
{
	char *p = &str[0];
	while(*p)
	{
		p++;
	}
	for(int i = 0; *p;p--)
	{
		str[i]= *p;
		i++;
	}
}

1.第二次的错误

①for内的代码不运行;while()循环进行的条件是*p所指向的不为空,在while结束时,*p指向的使字符串末尾的‘/0’,相当于*p指向NULL,而for循环进行的条件和while一样是*p指向不为空,所以在第三次编译的程序中while()循环结束后没有立即进行for()循环,而是先p--使p指向str的最后一个字符,而不是‘/0’

②定义指针用string会出错;*(str + i)也编译错误;现在在电脑上编译是正确的。

但是如果用str[i] = &str[j];//会提示[Error] invalid conversion from 'char*' to 'char' [-fpermissive];

第三次,算是成功一半了 


void reverse_string(string &str)
{
	char *p = &str[0];
	while(*p)
	{
		p++;
	}
	p--;
	for(int i = 0; *p;p--)
	{
		str[i]= *p;
		i++;
	}
}

1.第三次的修改:在for前加q--;字符串成功逆转;但hello变为olleo,感觉自己代码也没错啊,为啥可就是稍长的就一般倒序,剩下一半直接输出。//因为需要再加一个数组

第四次try


void reverse_string(string &str)
{
	char *p = &str[0];
    int i = 0;
	while(*p)
	{
		p++;
        i++;
	}
	p--;
    i--;
    int a;
	for(int j = 0; *p;p--)
	{
		a=str[i];
        str[i]=str[i];
        str[j]=a;
		i--;
        j++;
	}
}

第四次:之前的问题是指针指向数组,为数组的地址,因此不论如何都会重复,变为对称字符,但现在却是,用两个数组进行转换 ,但为何仍是对称;//str[i] = str[i],以前总是犯这种错误,肯定对称;就算是str[i] = str[j],也不会输出样例中的结果,因为这个循环相当于以中间的字符为对称轴,进行对称互换,进行到一半时已经得到想要的结果,但此时程序仍在进行,到最后把换过来的字符串由换回去了,无用功

1.str是字符串,也可以作为字符数组,用int声明a不如用char声明a

最后一次终于对了


void reverse_string(string &str)
{
	char *p = &str[0];
    int i = 0;
	while(*p)
	{
		p++;
        i++;
	}
    char a;
    p--;
    i--;
	for(int j = 0;i>j;i--,j++)
	{
		a=str[i];
        str[i]=str[j];
        str[j]=a;
        
	}
}

将i大于j,设为for进行的条件就可以实现一半转换,最后找到三变量交换法第二项本来是i与j的交换,结果变成了i与i的交换。

1p--忘记删除了while()循环结束时,p已经没有用处了。

2.while()循环的作用相当于计数器,使i=str的长度,可以i = str.sizeof()。。。。。错了qwq,sizeof是返回char数组的长度,而且sizeof的用法是sizeof(str),这里string应该使用size()函数,i = str.size();

3.for()循环的函数体中,三变量交换法可以换成swap()函数。

THE LAST of 第二个正确代码


void reverse_string(string &str)
{
    int i ;
    i = str.size();
    i--;
	for(int j = 0;i>j;i--,j++)
	{
        swap(str[i],str[j]);
	}
}

二)、 6-8 工作备忘录的生成(链表)

 每天都要处理很多事务,为了更好地安排工作,希望在每天开始工作前,根据工作记录,生成工作备忘录。首先输入工作记录数(大于0的一个整数),再逐条输入各条工作记录,每条工作记录包括:工作名,开始时间,结束时间。假设每项工作的开始时间均小于它的结束时间,并且各项工作的开始时间互不相同。

我们的工作是需要把这些工作记录按开始时间排序并输出,在输出时,如果某项工作与若干项工作冲突(在做该项工作时,需要同时做其它工作),则在该工作名前加'*'。

函数接口定义:

Node* add(Node *, Node *);
void display(Node *);

#include<iostream>
#include <string>
using namespace std;
struct Node{
    string name;
    int start;
    int end;
    Node *next;
};
Node* add(Node *, Node *);
void display(Node *);
bool check(Node *head)
{
    if(head==NULL || head->next==NULL) return true;
    Node *p=head->next;
    if(head->start > p->start) return false;
    return check(p);
}
int main()
{
    Node *head=NULL, *p;
    int i, repeat;
    cin>>repeat;
    for(i=0;i<repeat;i++){
        p = new Node;//创建一个结点
        cin>>p->name>>p->start>>p->end;
        p->next=NULL;
        head = add(head, p);
    }
    if(!check(head)) cout<<"ERROR"<<endl;
    display(head);
    return 0;
}

/* 请在这里填写答案 */

输入样例:

4
aaa 19 20
ccc 169 200
ddd 153 170
bbb 20 111

输出样例:

aaa 19 20
bbb 20 111
*ddd 153 170
*ccc 169 200

First

忽视add 函数声明;对add的作用错误

段错误


Node* add(Node *head, Node *p)//判断,加* 
{
		int i = 0;
	while(head->next != NULL)
	{
	
		if(head[i].end < p->start)
		{
			p->name = '*' + p->name;
			head[i].name = '*' + head[i].name;
		}
		i++;
	}
	return p -> next;
}
void display(Node *head)// 输出结构体 
{
	int i = 0;
	while(head->next != NULL)
	{
		cout<<head[i].name<<head[i].start<<head[i].end;
		cout<<endl;
		i++;
	}
}

 1.原来*是在display函数中加入,用insert函数来插入*,此处应使用数组名,而不是直接第一个class;最后输出是本来是让head->next不为空,但就少一个结点的class;因此改为head不为空,那么可以用head->next->end吗,芜湖~,可以欸

6.那么add函数是用来干什么的啊;是让p接到一head为头的链表中

2.此题不能用二表示维数组的方式来表示结构体,因为题中仅仅定义了一个结构体,结构体名->next是指向下一结点吗;此处的next是标识符, 可用p->next来代替p++;

3.此处的head和p有什么区别,p++再指向第一个元素时应重新赋值,由此可以让head仅在最后输出的时候用,其他地方用指针代替;

4.head->next与head = head->next不同,第一个表示下一个结点,但head仍然是原来的结点,第二个表示head已经是下一个结点(《数据结构c语言版》早知道就买c++版的了(lll¬ω¬)),那么add函数的作用就是让head还是第一个结点,但p指向第i+1个结点,那么是不是再弄一个指针head2,指向head,然后next循环,条件是head2不为空指针

5.不知道为啥在结构名后不加[],就用‘.’是编译错误,要是不加[]就是地址,编译错误 

SECOND


Node* add(Node *head, Node *p)//判断,加* 
{
	Node* temp = head;
	while(temp != NULL)
	{
		if(temp -> next == NULL)
		{
			temp -> next = p;
			break;
		}
		temp = temp -> next;
	}
	return head;
}
void display(Node *head)// 输出结构体 
{
	Node* headstar = head;
	while(headstar -> next != NULL)
	{
		if(headstar -> end > headstar -> next ->start)
		{
			if(headstar -> name[0] != '*')
			{
				headstar->name.insert(0,1,'*');
			}
			if(headstar -> next -> name[0] != '*')
			{
				headstar -> next -> name.insert(0,1,'*');
			}
		}
	 } 
	while(head != NULL)
	{
		cout<<head->name<<head->start<<head->end;
		cout<<endl;
		head = head ->next;
	}
}

 为空,两个函数都不对

1.display是在第一个循环中没有等于下一个元素

2.add函数中忘记第一个class在没有被p赋值前是空

半对了。

1.题目中有一个bool类型的函数,我以为不用管start的问题,没想到是隐藏项目,那么add究竟是不输入,还是转换,应当是转换吧

THIRD


Node* add(Node *head, Node *p)//判断
{
	if(head == NULL)//第一个结点 
    	{
    		head = p;
    		head->next=NULL;
    		return head;
    	}
	Node* head3 = head;
	int flag = 1;
	
	while(head3 != NULL )//使temp到达即将正在输入的一项与前一项 
	{
		if( head3 -> start > p -> start)
		{
			flag = 0;
			break;
		}
		head3 = head3 -> next;//temp停留在为空指针,即将输入的一个结点 
	}//结束时temp停留在即将录入的一项,或顺序错误的一项
	if(flag == 0)
	{
		Node *temp = p;
		p -> next = head3;
		 
	 } 
	 if(flag = 1)
	 {
	 	head3 = p;
	  } 
	while(head3 != NULL)
	{
		if(head3 -> next == NULL)
		{
			head3 -> next = p;
			break;
		}
		head3 = head3 -> next;
	}
	return head;
}
void display(Node *head)// 输出结构体 
{
	Node* headstar = head;
	while(headstar -> next != NULL)
	{
		if(headstar -> end > headstar -> next ->start)
		{
			if(headstar -> name[0] != '*')
			{
				headstar->name.insert(0,1,'*');
			}
			if(headstar -> next -> name[0] != '*')
			{
				headstar -> next -> name.insert(0,1,'*');
			}
		}
		headstar = headstar -> next; 
	 } 
	while(head != NULL)
	{
		cout<<head->name<<" "<<head->start<<" "<<head->end<<endl;
		head = head ->next;
	}
}

只输出第一行,应该是链表之间的数据传递有问题 

1.顺序出错时,head3转换


Node* add(Node *head, Node *p)//判断
{
	if(head == NULL)//第一个结点 
    	{
    		head = p;
    		head->next=NULL;
    		return head;
    	}
	Node* head3 = head;
	int flag = 1;
	Node* head4 = NULL; 
	while(head3 != NULL )//使temp到达即将正在输入的一项与前一项 
	{
		if( head3 -> start > p -> start)//表示顺序出错 
		{
			flag = 0;
			break;
		}
		head4 = head3;
		head3 = head3 -> next;//temp停留在为空指针,即将输入的一个结点 
	}//结束时temp停留在即将录入的一项,或顺序错误的一项
	if(flag == 0)
	{
		p -> next = head3;//将大于某项的放在插入的结点后面,在将插入结点插入当前位置 
		head3 = p;
		 
	 } 
	 if(flag == 1)
	 {
	 	head4 -> next = p;
	 	p -> next= head3;
	  } 
	return head;
}
void display(Node *head)// 输出结构体 
{
	Node* headstar = head;
	while(headstar -> next != NULL)
	{
		if(headstar -> end > headstar -> next ->start)
		{
			if(headstar -> name[0] != '*')
			{
				headstar->name.insert(0,1,'*');
			}
			if(headstar -> next -> name[0] != '*')
			{
				headstar -> next -> name.insert(0,1,'*');
			}
		}
		headstar = headstar -> next; 
	 } 
	while(head != NULL)
	{
		cout<<head->name<<" "<<head->start<<" "<<head->end<<endl;
		head = head ->next;
	}
}

倒序那里出了错 


Node* add(Node *head, Node *p)//判断
{
	if(head == NULL)//第一个结点 
    	{
    		head = p;
    		head->next=NULL;
    		return head;
    	}
	Node *head3 = head;
	int flag = 1;
	Node *head4 = NULL; 
	while(head3 != NULL )//使temp到达即将正在输入的一项与前一项 
	{
		if( head3 -> start > p -> start)//表示顺序出错 
		{
			flag = 0;
			break;
		}
		head4 = head3;
		head3 = head3 -> next;//temp停留在为空指针,即将输入的一个结点 
	}//结束时temp停留在即将录入的一项,或顺序错误的一项
	if(flag == 0)
	{
		p -> next = head3;//将大于某项的放在插入的结点后面,在将插入结点插入当前位置 
		head -> next = p;
		 
	 } 
	 if(flag == 1)
	 {
	 	
	 	head4 -> next = p;
	 	p -> next= head3;
	  } 
	return head;
}
void display(Node *head)// 输出结构体 
{
	Node* headstar = head;
	while(headstar -> next != NULL)
	{
		if(headstar -> end > headstar -> next ->start)
		{
			if(headstar -> name[0] != '*')
			{
				headstar->name.insert(0,1,'*');
			}
			if(headstar -> next -> name[0] != '*')
			{
				headstar -> next -> name.insert(0,1,'*');
			}
		}
		headstar = headstar -> next; 
	 } 
	while(head != NULL)
	{
		cout<<head->name<<" "<<head->start<<" "<<head->end<<endl;
		head = head ->next;
	}
}

正确了,但运行超时了,我改了6次!!!!,生气jpg。

上课笔记:

壹.先用head标记表头,建立*p,插入链表中

1.表头:*p->head,head = p;

2.中间:p.next=p.next -> q.next;q.next =q.next ->p.next;

3.结尾:p.next=p.next->q.next; q.next =q.next ->p.next;

贰.用struct标记链表

1.check用来检测工作表是否顺序

2.将while的循环条件改为。。。&& 比较;指针与head比较是从表头开始,每个class的比较,遇到不同的顺序不对;

叁:找到错误了

display中的比较只进行了一次,应该再加上一个指针,和两个for循环

三)、7-1 查找单价最高和最低的书籍

 编写程序,从键盘输入 n (n<10)本书的名称和定价并存入结构数组中,查找并输出其中定价最高和最低的书的名称和定价。

输出格式语句:

printf("highest price: %.1f, %s\n", );

printf("lowest price: %.1f, %s\n",);

输入输出示例:括号内为说明,无需输入输出

输入样例:

3	(n=3)
Programming in C
21.5
Programming in VB
18.5
Programming in Delphi
25

输出样例:

highest price: 25.0, Programming in Delphi 
lowest price: 18.5, Programming in VB 

第一次错误: 

#include<iostream>
#include<string>
#include<cstdio>

using namespace std;
struct book
{
	char name[80];
	float price;
};
int main()
{
	int n;
	cin>>n;
	struct book libery[10];
	for(int i = 0; i < n; i++)
	{
		scanf("%s",libery[i].name);
		cin>>libery[i].price;
	};
	int max = 0,min = 0;
	for(int i=1; i<n; i++)
	{
		if(libery[i].price > libery[max].price)
		{
			max = i;
		}
		
		if(libery[i].price < libery[min].price)
		{
			min = i;
		}
	}
	printf("highest price: %.1f, %s\n",libery[max].price,libery[max].name);
	printf("lowest price: %.1f, %s\n",libery[min].price,libery[min].name);
	return 0;
}

highest price: 0.0, in
lowest price: 0.0, Programming

分析:

最高最低价格为零,书名没有全部输出;scanf在读取缓冲区时,遇到空格、回车等空白符,会停止读取,剩下的字符串留在缓冲区中,getchar()只能读取一个字符;书名的第一个单词正确,还真是幸运

1.取消指针指向结构体数组,是否使用指针问题不大;这和指针关系不大,用不用都可以

2.getline(cin,libery[i].name[80]);编译错误

getline(cin,libery[i].name);编译错误;//此为getline全局函数用法课本第295页,需要用string对象储存字符串,但在上述程序中字符串用char储存,因此编译错误

cin.getline(libery[i].name,80);正确编译;//此为getline成员函数用法,用来处理用char储存的字符串

此时问题只剩下输入的数字问题

highest price: 1.5, Programming in C
highest price: 8.5, Programming in VB
highest price: 5.0, Programming in Delphi

发现问题,在cin之前加了一个getchar本想用来出去scanf未读取的空格,改为getline后不需要去除空格,因此getchar除去了输入的第一个字符 

   getchar();
    cin.getline(libery[i].name,80);getchar()
        cin>>libery[i].price;

以下为正确代码

#include<iostream>
#include<string>
#include<cstdio>

using namespace std;
struct book
{
	char name[80];
	float price;
};
int main()
{
	int n;
	cin>>n;
	struct book libery[10];
	for(int i = 0; i < n; i++)
	{
        getchar();
	cin.getline(libery[i].name,80);
		cin>>libery[i].price;
	};
	int max = 0,min = 0;
    
	for(int i=1; i<n; i++)
	{
		if(libery[i].price > libery[max].price)
		{
			max = i;
		}
		
		if(libery[i].price < libery[min].price)
		{
			min = i;
		}
	}
	printf("highest price: %.1f, %s\n",libery[max].price,libery[max].name);
	printf("lowest price: %.1f, %s\n",libery[min].price,libery[min].name);
	return 0;
}

 老师讲课:

gets已经被淘汰,建议使用fgets;

  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值