7.13关于数组7.15、指针7.14、7.20

来源:互联网 发布:mac右键没有剪切 编辑:程序博客网 时间:2024/06/16 14:50

数组

c++中
数组定义:不允许动态定义数组,只能逐个引用不能一次全部引用;
赋初值:不允许整体赋值。不允许用分号隔开赋值,数组分行赋值只能是逗号隔开,不同于matlab哦。变量使用必须先定义不同于MATLAB最近也在用MATLAB进行处理,千万别弄混啦。

//数组元素的引用#include <iostream>#include <stdlib.h>using namespace std;int main (){    int a[10],i;//数组的定义    for (i=0;i<10;i++)        a[i] = i ;//逐个赋值    for (i=9;i>=0;i--)        cout << a[i]<<' '; //逐个输出        cout << endl;    system ("pause");    return 0;}

数组的优势列举–一维:

1. 一个简单例子//裴波那契数列的数组前20个数据的输出
(1)赋初值。刚开始写错了,f[i]=f[i+1]+f[i-1]导致数组赋值为无,因为f[i+1]未知。
(2)for (i=0;i<= 20;i++)//i<=20 死循环了:可能是因为数组中f[20]不存在,导致程序跑飞了吧。
(3)f( i % 5 == 0) 运算符优先级别问题:算数运算符 高于关系运算符,关系运算符高于赋值运算符。
(4)每五个一换行:if ( i % 5 == 0)运行没问题,起初用的是while ( i % 5 == 0),死循环了。分析原因:
if ()是条件判断语句,满足即执行, 还有switch();
while()是循环判断语句,满足即循环。 for switch while都是循环语句。

for (i=0;i< 20;i++)    {        while ( i % 5 == 0)//   每五个一行,换行语句%5在前面           cout << endl;        cout << f[i] << ' ';//逐个输出 空格隔开   //cout << setw(8)<< f[i]     }

(5)数据形式输出不好看,采用设置位宽的方法
需要声明流控制头文件 include [ iomanip ]

cout << setw(8)<< f[i] << ' ';

这样写的话是一个循环嵌套for>>while,初始条件0%5==0的逻辑值为1,满足,循环一直执行。
区分清楚纯粹的判断语句和循环语句。

//裴波那契数列的数组前20个数据的输出#include <iostream>#include <stdlib.h>#include <iomanip>using namespace std;int main (){    int i,f[20]={1,1};    for (i=2;i<20;i++)           f[i]=f[i-2]+f[i-1];//赋初值。刚开始写错了,f[i+1]导致数组赋值为无    for (i=0;i< 20;i++)//i<=20 死循环了:难道是因为数组中f[20]不存在,导致程序跑飞了么。。    {        if ( i % 5 == 0)//   每五个一行,换行语句%5在前面           cout << endl;        cout << setw(8)<< f[i] << ' ';//逐个输出 空格隔开   //cout << setw(8)<< f[i]     }    system ("pause");    return 0;}

2. 起泡法对10个数进行排序:小到大
起泡法思路P138:如果有n个数,要进行n-1趟比较和交换;在第1趟中需进行n-1此两两比较,会沉淀出最大的数,在第j趟中需进行n-j次两两比较。
Analysis:每趟比较中还要比较——双重循环(循环嵌套)。
传说中的冒泡法也不过如此。
for ( i=0 ; i < 9 ; i++ )//趟–n-1
for ( j =0 ;j < 9-i;j++)//第x趟内比较次数——n-x

//n=10,起泡法进行排序#include <iostream>#include <stdlib.h>using namespace std ;int main (){    int i,j,t,a[10];    cout << "please input 10nums:"<< endl ;    for ( i=0 ; i < 10 ; i++ )        cin >> a[i] ; //输入可以不要空格,默认不接受空格作为目标字符    cout << endl;//获得数组内容    //排序    for ( i=0 ; i < 9 ; i++ )//趟--n-1        for ( j =0 ;j < 9-i;j++)//第x趟内比较次数——n-x            if (a[j]>a[j+1])            {                t=a[j];                a[j]=a[j+1];                a[j+1]=t;            }    cout << "the sorted number is :" << endl;    //进行数据输出    for ( i=0 ; i < 10 ; i++ )        cout << a[i] << ' ';    cout << endl;//获得数组内容    system ("pause");    return 0;}

二维数组

定义:a[3][4]按行存放;和引用形式一样但要区分开a[3][4]。
初始化:分行赋值;直接赋值所有;部分元素赋值,其余默认为0(不同于昨天的任意值 静态局部变量 赋值,不赋值的话,为任意值);
引用:不要超过范围。
1. 交换矩阵行列。

#include <iostream>#include <stdlib.h>using namespace std;int main (){    int a[2][3]={{1,2,3},{4,5,6}};    int b[3][2],i,j;    cout << "array a :"<<endl;    for (i=0;i<2;i++)  //把a的输出和交换操作放在了一起    {        for (j=0;j<3;j++)        {            cout << a[i][j] << " ";            b[j][i]=a[i][j];        }        cout <<endl;//进行规范的输出    }   for (i=0;i<3;i++)  //把a的输出和交换操作放在了一起    {        for (j=0;j<2;j++)            cout << b[i][j] << " ";        cout <<endl;    }system ("pause");return 0;}

2.求取矩阵中最大元素值 及其所在行号和列号
问题分析:本质上还是对一列数进行排序。起泡法的具体化应用:数组序列,但是只应用了一次,因为只用求最大的数

#include <iostream>#include <stdlib.h>using namespace std;int main(){    int i,j,max;int row,colum; //为了输出row和column,必须设置这样的变量存储行和列。    int a[3][4]={{5,12,23,56},{19,28,37,46},{-12,-34,6,8}};    max=a[0][0];    for (i=0;i<3;i++)        for (j=0;j<4;j++)            if (a[i][j]>max)            {                max=a[i][j];                row=i;                colum=j;            }    cout << "max="<< max << ";row=" << row << ";colum=" << colum ;    system ("pause");    return 0;}

数组名作函数参数

像常量和变量一样,数组元素也可作为函数实参,用法同变量相同;数组名可作实参和形参,传递的是数组起始地址。
1.数组元素作实参
同上题一样,只是比较部分专门设了函数,通过使用数组元素作实参调用函数。
实参和形参传递,声明函数,

int max_value(int x,int max);//声明函数  还有就是函数里的这个变量不用定义的么???max=max_value(a[i][j], max);//实参和形参传递
//算法思路:开始赋值给a[0][0],然后于每一个比较,替换为大的;一直这样。本质上就是起泡法,是一个具体化了的#include <iostream>#include <stdlib.h>using namespace std;//先定义比较函数int max_value(int x,max)的话,还需要给出max,更麻烦。//不如先定义主函数,再写其他函数,这样只需主函数里多加一句声明函数即可。int main(){    int max_value(int x,int max);    int a[3][4]={{5,12,23,56},{19,28,37,46},{-12,-34,6,8}};    int i,j,max,row,colum;      max=a[0][0];    for (i=0;i<3;i++)        for (j=0;j<4;j++)            {                max=max_value(a[i][j], max);                if ( max = a[i][j])                {                row=i;                colum=j;                }            }    cout << "max="<< max << ";row=" << row << ";colum=" << colum ;system ("pause");return 0;}int max_value(int x,int max){    if (x>max) return x ;    else return max;}

2.一维数组名作函数参数
选择法对一个一维数组中的n个元素进行排序:由小到大。
刚开始理解起来很吃力,后来发现还好,只是变量换成数组的形式问题:输入输出(循环for),形参实参(int array[] 、 a)。
数组名作函数形参(其实本质是指针的理解)细节理解:
(1)如果函数实参为数组名int array[]——地址,形参也应为数组名——地址(或者指针变量)。
(2)数组名为实参时,形参可以是数组名指针变量,用来接收实参传来的地址。调用函数时,实参数组和形参数组占据同一段内存单元。所以形参数组中各元素的变化会相应改变实参数组中元素值。这一点不同于变量作函数哦(只把实参传递给形参,形参变不影响实参)。可以利用这一特性改变实参数值和指针类似。

#include <iostream>#include <stdlib.h>using namespace std;int main (){    void select_sort(int array[] ,int n);//函数声明    int a[10],i;    cout<<"enter the originl array:"<<endl;    //输入数组的十个数    for (i=0;i<10;i++)    cin >> a[i];    cout <<endl;    //函数调用,数组名作实参    select_sort( a,10);    //结果输出    for (i=0;i<10;i++)      cout << a[i]<<" ";    cout << endl;    system ("pause");    return 0;}void select_sort(int array[],int n) {    int i,j,k,t;    for (i=0;i<n-1;i++)    {        k=i;        for (j=i+1;j<n;j++)            if (array[j]<array[k])                k=j;//找最小的数的啊        t=array[k];array[k]=array[i];array[i]=t;//交换:把最小的数调换过来    }}

3.多维数组名作函数参数
必须指明列数

//一个3*4矩阵,用函数求其最大值#include <iostream>#include <stdlib.h>using namespace std;int main (){    int max_value(int a[][4]);//数组定义,列不可省略    int a[3][4]={{11,32,45,67},{22,44,66,88},{15,72,43,37}};    cout << "最大值是:" << max_value(a) << endl;//起初忘记了(a),导致结果输出的是对应ascii码。    system ("pause");    return 0;}int max_value(int a[][4]){    int i,j,t,max;    max = a[0][0];        for (i=0;i<3;i++)            for(j=0;j<4;j++)                if (a[i][j]>max) max=a[i][j];    return max;                 }

字符数组

指针

基本介绍

编译时会在内存区给变量(客户)分配内存单元,每个字节有一个编号,即“地址”,相当于旅馆房间号。就像客人主旅馆。凭借房间号(地址)来对客户(变量)进行存取操作。

指针即某变量 i 的地址。指针变量是存放指针/地址的变量,和普通变量的区别在于它是指向变量的变量。符号表示*,表示指向例如:i_pointer是一个指针变量,*i_pointer是i_pointer所指向的变量i。

i=3;*i_pointer=3;

直接存取(访问)方式:按变量地址存取变量值。
间接存取(访问)方式:将地址存放在另一个变量中,即指针变量。例如:

i_pointer = &i; &取地址运算符。

指针变量的定义引用

示例说明:
*不是变量名一部分;分配四个字节存储单元;
数字不能直接赋给指针变量,不被认为是字节编号;
必须指明基类型:原因为——

int *pointer1;//pointer1是指向整数的指针变量float *pointer2;//pointer2是指向浮点型的指针变量char *pointer3 = &i;//pointer3是指向双精度型的指针变量

&取地址运算符
*间接访问的运算符

#include <iostream>#include <stdlib.h>using namespace std;int main(){    int a,b;    int *pointer1,*pointer2;    a=100;b=10;    pointer1=&a;pointer2=&b;//&取得是地址    cout << a << " " << b  << endl;    cout << *pointer1 <<  " " << *pointer2<< endl;//*pointer表示间接访问输出变量值    system ("pause");    return 0;}

指针变量处理交换两个数,输出大数。
//方法二:采用交换指针变量值 对其指向的数进行交换操作交换p1 p2 值,a b值不变。
//方法一:先比较两个数,然后将大数地址赋给p1

//方法一:先比较两个数,然后将大数地址赋给p1#include <iostream>#include <stdlib.h>using namespace std;int main (){    int a,b,*p1,*p2;//定义整型变量和指针变量*    // 起初多定义了个int p;提示出错:int与int* 的间接寻址级别不同     cin >> a >> b;    //p1 = &a;    //p2 = &b;//使得指针变量分别指向两个数 再通过比较大小 使得指针1始终指向大数    if ( a<b )       {p1 = &b;p2 = &a;}    else        {p1 = &a;p2 = &b; }    cout << "max=" << *p1<< " " << "min=" << *p2 << endl;    system ("pause");    return 0;}//方法二:采用交换指针变量值 对其指向的数据首地址进行交换操作int main (){    int a,b,*p1,*p2,*p;//定义整型变量和指针变量*    // 起初多定义了个int p;提示出错:int与int* 的间接寻址级别不同     cin >> a >> b;    p1 = &a;    p2 = &b;//先使得指针变量分别指向两个数;再通过比较大小 使得指针1始终指向大数    if ( a<b )//交换指针变量值,也就相当于交换了指向的变量首地址       {p = p1;p1 = p2;p2=p;}    cout << "max=" << *p1<< " " << "min=" << *p2 << endl;    system ("pause");    return 0;}

交换指针变量的操作:p = p1;p1 = p2;p2=p;和普通的交换变量没有区别。

指针作函数参数

上题的方法3:不改变指针变量指向的变量首地址,而通过间接访问元素方式来交换其所指向变量的内容。交换a、b值,p1 p2 值不变。

#include <iostream>#include <stdlib.h>using namespace std;int main (){    void swap (int *p1,int *p2);//不需要返回值,只用进行两个数的交换操作即可。    int a,b,*point1,*point2;//定义整型变量和指针变量*    cin >> a >> b;    point1=&a;point2=&b;    if (a<b)        swap (point1,point2);//传递的实参指针变量    cout << "max=" << *point1<< " " << "min=" << *point2 << endl;    system ("pause");    return 0;}void swap(int *p1,int *p2 )//括号内需指明操作数类型---指针变量的定义    //函数的作用是 通过间接访问指针变量 交换其所指向的变量内容  {   int tem;//不能定义为*tem 因为*tem本身已经是整型变量了,而不是指针变量。   tem = *p1;*p1=*p2;*p2=tem;//   }

(1)对比和体会语句:

p tem 都是指针变量;p = p1;p1 = p2;p2=p;//交换指针变量值 对其指向的数据首地址进行交换操作tem = *p1;*p1=*p2;*p2=tem;//通过间接访问指针变量 交换其所指向的变量内容

(2)不要将作为函数参数的 声明语句写成了

if (a<b)  swap (point1,point2);正确if (a<b)  swap (*point1,*point2);错误

原因分析:
swap函数void swap(int *p1,int *p2 )的两个形参是“基类型为整型”的指针变量,point12为指针变量,而*point12是 整型变量,后一种写法的话形参和实参不匹配。

概念加强:指针是可以通过形参和实参来改变变量数值的,同数组一样,其所指向的是同一个对象。参见笔记本
总结通过调用函数使得变量的值发生变化,在主调函数中使用这些改变了的值。——指针变量和数组做参数
但是呢,不能通过改变形参指针变量的值而使实参指针变量的值改变。
原因分析及示例:没理解 记住好了。。

原创粉丝点击