第03章 CORE C++_枚举_数组_结构_指针(I)

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);// 俩行与上一行等价  
            }  
   解释:函数也有地址;格式:返回类型 函数名(参数表) 

      

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值