1.问题:定义颜色和类型,输出其值
思路:无
代码:#include<iostream>
using namespace std;
enum Color{BLACK,GREEN,RED=5,YELLOW=9,BLUE};
enum Type{SHIRT,CAP,SOCKS,SHOES};
int main()
{
Color c;
Type t=SHIRT;
c=RED;
cout<<"c="<<c<<endl;
cout<<"t="<<t<<endl;
t=CAP;
c=YELLOW;
cout<<"c="<<c<<endl;
cout<<"t="<<t<<endl;
}
解释:1.自定义数据类型:枚举,结构,指针
2.枚举:用名字来代表数字,本质上枚举都是整数。如:enum Color/Type/Mode{...};
枚举的作用:让整数的含义更清晰;枚举可以用在switch...case... 中;可以用枚举进行类型检测
如果没有指定,就表示比前一个数增加1(BLUE=10),如果第一个也没有指定,那么第一个就是0
枚举只是类型名,而{}里面的习惯用大写,称之为枚举常量
2.问题:从变量输入10个整数,按相反顺序输出
思路:可以用不同方法存储10个数,顺序或逆序输出可用简单的数组形式
代码:#include<iostream>
using namespace std;
int main()
{
cout<<"input 10 integers:"<<endl;
int a[10];
for(int i=0;i<10;i++)
cin>>a[i];
for(int j=9;j>=0;j--)
cout<<a[j]<<' ';
cout<<endl;
//如果把上面数组的内容颠倒过来:
/*for(int k=0;k<5;k++){
int t=a[k];
a[k]=a[9-k];
a[9-k]=t;
}
for(int i=0;i<10;i++)
cout<<a[i]<<' ';
cout<<endl;*/
}
解释:数组:一组相同类型的数据,在内存中连续存放的
元素的数据类型 定义数组: 数组名[元素个数];元素个数必须是整数常数
数组名[下标]用来访问某个数据,下标从0开始。如:int a[80]; 使用时是a[0]~a[79], 而没有a[80]; 下标超越范围称为越界;
要输出整个数组:决不能直接输出数组名,必须用一个循环逐个输出,输入也一样;错误输出:cout<<a<<endl;
3.问题:数组初始化
思路:无
代码:#include<iostream>
using namespace std;
void print(int x[5])
{
for(int i=0;i<5;i++)
cout<<x[i]<<' ';
cout<<endl;
}
int main()
{
int a[5]={10,20,30,40,50};//5可以省略,但不要求那么做
int b[5]={};
int c[5];
print(a);
print(b);
print(c);
}
解释:初始化:当数组的初始数据不够时,系统自动补0;int b[5]={}; 表示为数个0;而int c[5]; 表示为垃圾数据;
4.问题:数组名,数组的用法
思路:无
代码:#include<iostream>
using namespace std;
int main()
{
int a[5]={10,20,30,40,50};
cout<<"a="<<a<<endl;
cout<<"&a[0]="<<&a[0]<<endl;
cout<<"*a="<<*a<<endl;
*a=888;
cout<<"a[0]="<<a[0]<<endl;
cout<<"&a[3]="<<&a[3]<<endl;
cout<<"a+3="<<a+3<<endl;
cout<<"a[3]="<<a[3]<<endl;
cout<<"*(a+3)="<<*(a+3)<<endl;
cout<<"*(3+a)="<<*(3+a)<<endl;//思考题,呵呵
cout<<"3[a]="<<3[a]<<endl;//思考题,呵呵
}
解释:用数组名作形参的时候,数组名表示一个数的时候,指的是第一元素的地址。所以:*a等价于a[0]
数组名a+i下标等于a[i]
5.问题:越界现象
思路:超越原有数据空间数据进行访问修改
代码:#include<iostream>
using namespace std;
int main()
{
int x=100;
int a[4]={1,2,3,4};
int y=200;
for(int i=0;i<40;i++) //越界
a[i]=123; //越界赋值
cout<<"x="<<x<<endl;//非越界时应为100
for(int i=0;i<4;i++)
cout<<a[i]<<' ';
cout<<endl;
cout<<"y="<<y<<endl;// 非越界时应为200
for(int i=1;i<2;i++)
a[-i]=0;//非法赋值
cout<<"y="<<y<<endl;//已超出正常范围,即不可知其值(也就是值不确定为某值)
}
解释:对数组进行越界访问时,往往会破坏其它变量的数据
6.问题:数组定义及输出
思路:无
代码:#include<iostream>
using namespace std;
int main()
{
int a[5]={0x41414141,0x42424242}; //(???)
char b[4]={'a','s','d','f'};
char c[4]={'a','s','/0','f'}; //'/0'为数组结束符,其后字符不属于c[4]数组
cout<<"a="<<a<<endl;
cout<<"b="<<b<<endl;
cout<<"c="<<c<<endl;
char name[20]={"lionkingchina"};// 大括号可以省略,后面有默认‘/0‘ ,且占字符串一个位置;
cout<<"name="<<name<<endl;
cout<<name+1<<endl;
cout<<name+3<<endl;
cout<<name[4]<<endl;// 输出字符元素,即,是第5号元素
}
解释:无
7.问题:用制表符和空格,转义字符换行和endl换行两种方法输出4行3列二维数组
思路:1.外循环:{{内循环:输出+制表符}endl;}
2.内循环:A?B:C形式,判断j%3=0?'/n':' '
代码:#include<iostream>
using namespace std;
int main()
{
int sits[4][3]={
{8,9,10},//sits[0]
{22,23,24},//sits[1]
{36,37,38},//sits[2]
{50,51,52}//sits[3]
};
for(int i=0;i<4;i++){
for(int j=0;j<3;j++){
cout<<sits[i][j]<<'/t'; //转义字符:'/t'制表符
}
cout<<endl;
}
for(int i=0;i<12;i++)
cout<<sits[0][i]<<(i%3==2?'/n':' ');
cout<<endl;
}
解释:无
8.问题:输入5个数,进行从小到大的排序
思路:1.输入5个数到一维数组
2.1.定义i和j位置,j的初始位置在i位置后一位
2.2.循环判断i,j位置数值,a[i]>a[j]:数互换位置;a[i]<=a[j]:数的位置不变;i位置不变,j到最后位置时,内循环结束
2.3.i+1,即i后移一位,j位仍在i位之后,即j实际也后移了一位,然后开始进行j循环,j到最后位置时,内循环结束;...一次外循环,i至数组倒数第二位时,外循环结束;(排序完毕)
3.输出数组
代码:#include<iostream>
using namespace std;
#include<algorithm>//如果用不了swap 就加这个头文件
int main()
{
int a[5];
cout<<"input 5 integers:";
for(int i=0;i<5;i++)
cin>>a[i];
for(int i=0;i<5;i++)
for(int j=i+1;j<5;j++)
if(a[j]<a[i])
swap(a[i],a[j]); //调换a[i],a[j]位置
for(int i=0;i<5;i++)
cout<<a[i]<<' ';
cout<<endl;
}
解释:案例:输入3 9 2 6 5;
过程:1.39265
2.29365
3.29365
4.29365
5.23965
6.23965
7.23965
8.23695
9.23596
10.23569
9.问题:在main中准备2个int数组,用findmax函数找出每个数组中的最大元素值,输出它们
思路:1方法:可以对每个数组先用上列方法排序,然后输出最后一数即可
2方法:设定一个变量两个数比较,大值输入其中,然后继续循环往下比较(与变量值比较);当然,小值时变量值不变;直到与最后一位数比较,输出变量值。(本代码为2方法)
代码:#include<iostream>
using namespace std;
int findmax(int x[],int n)
{
int max=x[0];
for(int i=1;i<n;i++)
if(x[i]>max)
max=x[i];
return max;
}
int main()
{
int a[5]={3,1,2,9,7};
int b[6]={8,5,7,2,1,6};
cout<<findmax(a,5)<<endl;
cout<<findmax(b,6)<<endl;
}
解释:数组定义时必须指定长度,只有在作为形参的数值时是可以省略的
10.问题:输入电视机,手机,冰箱,电脑的产品名(就是这四个名词),价格,代码,日期。依次输出
思路:1.定义电视机,手机,冰箱,电脑变量类型为结构体
2.初始化电视机,手机,冰箱,电脑变量:电视机,手机为默认形式初始化;冰箱为赋值形式初始化;电脑为输入形式初始化
3.输出
代码:#include<iostream>
using namespace std;
#include<string>
struct Product{
string name;
double price;
long code;
int date;
};//别忘了结尾后的分号
void show(Product p)
{
cout<<p.name<<':'<<p.price<<','<<p.code<<','<<p.date<<endl; //cout<<p1<<endl;这样些是不可以的,输入同理
}
Product input()
{
Product p;
cout<<"input product name,price,code and date:";
cin>>p.name>>p.price>>p.code>>p.date; //cout<<p1<<endl;这样些是不可以的,输入同理
return p;
}
int main()
{
Product p1={" 电视机",3000.0,10001,20080508};
Product p2={" 手机",1295.0,10013,20080610};
Product p3;
p3.name="冰箱";//.name成员运算符
p3.price=2138.5;//.price 成员运算符
p3.code=10037;//.code 成员运算符
p3.date=20080105;//.date 成员运算符
show(p1);
show(p2);
show(p3);
p1=input();
show(p1);
}
解释:1.结构类型:将不同类型的相关数据信息组织在一起,是用户自定义的类型,需要先声明类型的定义才能使用
结构与数组的区别:数组只是同一个数据类型的聚集,数组本身不是一个新的数据类型
2.数组结构类型初始化方法(部分代码):
int main()
{
Product a[3]={
{"电视机",3000.0,10001,20080508},
{"手机",1295.0,10013,20080610}
};
a[2].name=" 冰箱";//.name 成员运算符
a[2].price=2138.5;//.price 成员运算符
a[2].code=10037;//.code 成员运算符
a[2].date=20080105;//.date 成员运算符
for(int i=0;i<3;i++)
show(a[i]);
a[0]=input();
show(a[0]);
}
11.问题:指针变量和变量的地址与值的关系
思路:cout<<p;cout<<*p;cout<<&a;cout<<a;
代码:#include<iostream>
using namespace std;
int main()
{
int a=100;
int b=200;
int* p=NULL;
// cout<<*p<<endl;// 语法对,但逻辑错误,会导致段错误>!
p=&a;
cout<<"p="<<p<<endl;
cout<<"*p="<<*p<<endl;
cout<<"&a="<<&a<<endl;
cout<<"a="<<a<<endl;
short s=0x2468;
//p=&s;//用指针保存地址时,要保持类型一致。而int* p;short s;
*p=300;
cout<<"now,a="<<a<<endl;
}
解释:指针:也是一种变量,保存别的变量的地址。比喻:指针好比钱包,但钱包里放着是卡,卡联系都钱。
指针的作用:间接访问目标变量
注意:定义指针的时候需要说明类型,用*表示地址而不是取地址。int *p;地址变量
空指针:int* p=NULL; 或者char* r=0;两个是一样的
定义指针时总带个‘=’,就不会容易出错,良好的编程习惯
12.问题:使用指针变量和变量作为形参的赋值函数,改变原变量值并输出
思路:1.指针作为形参
2.形参赋值与实参赋值
代码:#include<iostream>
using namespace std;
void change(int* p)
{
*p=200;//这是给指针指向的地址空间赋值;int* p=&a;可以改写为int *p;p=&a;
//int n=200; //如果这两行代替上一行,将不会改变a的值。
//p=&n; //如果这两行代替上一行,将不会改变a的值。
}
void func(int x)
{
x=300;//赋值的是形参和实参没有关系!(???)
}
int main()
{
int a=100;
//int* p=&a;//这两行加起来等价于change(&a);
//*p=200; //这两行起来等价于change(&a);
change(&a);//传的时候要带地址!
cout<<"a="<<a<<endl;
func(a);
cout<<"a="<<a<<endl;
}
解释:操作*p才能操作变量a,其他的没有用;操作指针,根据*号找变量
13.问题:用形参改变实参的值的几种情况
思路:1.形参为指针变量
2.返回值保存到变量
代码:#include<iostream>
using namespace std;
void f1(int x)
{
cout<<"&x="<<&x<<endl;
x+=5;
}
int f2(int x)
{
x+=6;
return x;
}
int main()
{
int a=100;
f1(a);
cout<<"&a="<<&a<<endl;
cout<<"a="<<a<<endl;
f2(a);
cout<<"a="<<a<<endl;
a=f2(a); //返回值改写a值
cout<<"a="<<a<<endl;
}
解释:形参是一个独立与实参的变量,但是由实参初始化,只要初始化后就各不相干了。
只要两种运算法能改变变量的值,++ -- 和==
14.问题:用指针输出数组,改变数组元素值
思路:数组名也是地址,而指针也是地址
代码:#include<iostream>
using namespace std;
int main()
{
int a[5]={2,4,6,8,0};
int* p=NULL;
p=a;//注意用法
cout<<"p="<<p<<endl;
cout<<"a="<<a<<endl;
for(int i=0;i<5;i++)
cout<<p[i]<<' ';
for(int i=0;i<5;i++)
p[i]+=10;
for(int i=0;i<5;i++)
cout<<p[i]<<' ';
cout<<endl;
for(int i=0;i<5;i++)
cout<<a[i]<<' ';
cout<<endl;
}
解释:如果指针中保存的是数组地址,可以当作数组名能用;并且可以改变对应下标的数组元素值
15.问题:
思路:
代码:
解释:
16.问题:
思路:
代码:
解释:
17.问题:不同类型16进制数由对应指针输出其值,输出字符指针整型值,长整型数据变成字符型数据
思路:1.初始化长整型,短整型,字符型16进制变量
2.定义各类型变量对应的指针变量
3.输出各指针变量
4.输出字符指针整型值
5.16进制长整型数值变成字符型数值保存,然后把这个地址给字符指针
代码:#include<iostream>
using namespace std;
int main()
{
long v1=0x41424344;// 不是地址,表示16进制
cout<<v1<<endl;// 输出时都是以10进制输出,但输出地址是16进制。
cout<<showbase<<hex<<v1<<endl;
short v2=0x4748;
char v3=0x49;
long* p1=&v1;
short* p2=&v2;
char* p3=&v3;
cout<<*p1<<endl;//通过地址找变量只能找一个和指针相同类型的变量
cout<<*p2<<endl;//通过地址找变量只能找一个和指针相同类型的变量
cout<<*p3<<endl;//通过地址找变量只能找一个和指针相同类型的变量
cout<<(int)*p3<<endl;// 如果没有int强转换则显示I即49
p3=(char*)&v1; //16进制长整型数值变成字符型数值保存,然后把这个地址给字符指针
cout<<*p3<<endl;//cout<<p3<<endl;为何出错???
}
解释:hex以后改用16进制输出,但没有0x,本程序中未用到此功能。
showbase显示16进制格式0x带着,本程序中未用到此功能。???
18.问题:不同类型16进制数由对应指针输出其值,但没有0x
思路1:分步类型转换
思路2:统一类型转换
代码1:#include<iostream>
using namespace std;
void show(char* addr,int bytes)
{
for(int i=0;i<bytes;i++)
cout<<hex<<(int)*addr++ <<' '; //hex以后改用16进制输出,但没有0x
cout<<endl;
}
int main()
{
long v1=0x41424344;
short v2=0x4546;
char v3=0x47;
show((char*)&v1,sizeof(v1));// 注意类型转换
show((char*)&v2,sizeof(v2));
show((char*)&v3,sizeof(v3));
}
代码2:#include<iostream>
using namespace std;
void show(void* addr,int bytes)//void* 不管哪种地址
{
char* p=(char*)addr;// 注意统一类型转换
for(int i=0;i<bytes;i++)
cout<<hex<<(int)*p++ <<' '; //hex以后改用16进制输出,但没有0x
cout<<endl;
}
int main()
{
long v1=0x41424344;
short v2=0x4546;
char v3=0x47;
show(&v1,sizeof(v1));// 注意没有用类型转换
show(&v2,sizeof(v2));
show(&v3,sizeof(v3));
}
解释:变量在不同系统中,各个字节的存取顺序可能不同
用void*的时候总是要做类型转换
19.问题:结构类型指针的使用
思路1:定义结构类型;初始化结构类型变量;传递地址为形参,调用子函数输出
思路2:请试着改成只有一个主函数,却完成相同功能的程序
代码:#include<iostream>
using namespace std;
struct person{
char name[20];
bool gender;
int age;};
void show(person* p)
{
//cout<<(*p).name<<endl;// 注意优先级
cout<<p->name<<endl;
}
int main()
{
person furong={" 芙蓉",false,38};
show(&furong);// 地址
}
解释:(*指针).成员与指针-> 成员完全等价
20.问题:输入10个数,输出最大值
思路1:输入数列;挨个比较大小;输出最大值
思路2:请用数组作为形参构造输入和选取最大值子函数(取得最大值有两种方法:排序和本程序中方法)
代码:#include<iostream>
using namespace std;
void input(int* p,int n)
{
for (int i=0;i<n;i++)
cin>>*p++;//*(p+i),*(i+p) 等价
}
void getmax(int* p,int n, int* m)
{
*m=*p;
for(int i=0;i<n;i++)
if (*m<p[i])
*m=p[i];
}
int main()
{
int a[10];
input(a,10);// 在a数组中输入10个整数
int max;
getmax(a,10,&max);// 把a中最大元素的值存入max中
cout<<"max="<<max<<endl;
}
解释:掌握多种方法,多种结构,多种角度实现同一功能
21.问题:二级指针的使用
思路:指针的指针:要有一级做铺垫
代码:#include<iostream>
using namespace std;
int main()
{
int v=100;
int* p=&v;
int** q=NULL;
q=&p;
cout<< **q<<endl;
}
解释:无
22.问题:const对指针应用
思路:const固定指针指向数据和固定地址
代码:#include<iostream>
using namespace std;
int main()
{
int v1=100;
int v2=200;
const int* p=NULL; //const对*q进行固定,即固定其指定地址的数据
p=&v1;
//*p=300;//ERROR!
p=&v2;
int* const q=&v1;//const对q进行固定,即固定其指定地址
//q=&v2;//ERROR!
}
解释:无
23.问题:const可否固定形参?
思路:const固定形参的子函数
代码:#include<iostream>
using namespace std;
void show(int* p,int n)
//void show(const int* p,int n)//将会出错
{
*p=100;
for(int i=0;i<n;i++)
cout<< *p++<<' ';
cout<<endl;
}
int main()
{
int a[5]={10,20,30,40,50};
show(a,5);
}
解释:const 的数据只可以用但不可以改
24.问题:函数指针的使用
思路:???
代码:#include<iostream>
using namespace std;
void Double(int* a,int n)
{
for(int i=0;i<n;i++)
a[i]*=2;//a[i]+=a[i];a[i]<<=1;都可以用
}
void Print(int* a,int n)
{
for(int i=0;i<n;i++)
cout<<a[i]<<' ';
cout<<endl;
}
int main()
{
void (*p)(int* ,int)=Double;//& 可有可无,如不赋值就为垃圾数据
int a[5]={1,2,3,4,5};
(*p)(a,5);
//Print(a,5);
p=Print;//俩行与上一行等价
p(a,5);// 俩行与上一行等价
}
解释:函数也有地址;格式:返回类型 函数名(参数表)