C语言学习笔记_数组

来源:互联网 发布:淘宝韩国美女模特 编辑:程序博客网 时间:2024/04/30 14:26

第七章数组

*****2016年1月24日09:29:58
*韩–
*主要内容:数组是类型相同数据的集合
1、数组概述
2、一维数组的声明、初始化、使用
3、数组的运算、函数作为函数参数的用法
4、字符数组、字符串,以及字符串处理函数
5、多维数组的声明与使用、存储结构、初始化方法
6、冒泡排序、矩阵运算、分治与二分查找、
逆波兰表达式的生成,以及基于栈值的逆波兰表达式求值

//7-1数组概述

数组是确定个数的类型相同数据的集合,数组属于构造类型,他是相同数据类型数据的集合数组的特点:{    1、数组中的元素按顺序在内存中连续存放    2、数组内各个元素的数据类型相同    3、数组由数组名和下标构成,数组名是数组的首地址    4、下标由小到大,地址由低到高}

//7-2一维数组

可用于表示一个线性数据队列先声明、初始化,然后使用{    声明:{        形式:        [存储类型说明符][类型修饰符] 类型说明符 数组名[常量表达式]={初值表};        //存储类型说明符:extern(修饰成外部数组)、static(修饰成静态数组)        //类型修饰符:const(常量数组)、volatile可变数组            ///可变数组:指元素之值可以被其他程序修改,如中断服务程序        //数组名是一个标识符,是一个地址常量,元素的首地址,内存的起始地址            ///数组名具有非左值特性,因此不能对数组名进行赋值操作        //[]:下标操作符,系统提供的预定义函数        数组声明举例:{        ///几种声明形式:            # define SIZE 10        //            int arry[5];            //声明一个数组            double d[5],e[SIZE];    //同时声明两个数组            char name[SIZE*5];      //常量表达式        ///C99之后的标准中合法(visulC++ 6.0中非法):            unsigned int size = 10;            char str[size],buffer[2*size];        ///带类型修饰符的声明:            static int y[10];            extern double s[2];     //一个外部函数的引用性说明        }    }    初始化:{        int y[5] = {1,2,3,4,5};     //初值表初始化,该处数组所有的值        double d[] = {1.2,2.3,21.3};//初值表中的初值个数决定数组长度        int a[5] = {5,3,2};         //部分初始化只能省略最右边连续初值        ///error:        int b[6] = {1,,3,,5,};      //        /** 具有局部作用域的初值,如果不初始化,元素默认是随机的。            对于外部数组和静态数组其默认值为为0**/    }    使用:注意下标越界    }存储结构:{    //数组中的元素从数组名标明的起始地址按顺序在内存中连续存放    //不同类型的数组由与元素的类型不同,每个元素在内存中占有的字节数也不同    //下标加1,数组元素地址加 1*一个数组元素类型所占的的字节数}数组运算:{    //只支持数组元素间的运算以及数组元素下标的运算}一维数组作为函数调用:{    //在c语言中参数的传递分为两类:参数传值、参数传址    //数组作为函数参数时可用参数名或者数组元素的地址作为实参    //在被调用函数中,将形参声明为形式数组(即在方括号表示的下标操作符中不给出下表的数组)    冒泡排序:{
# include <stdio.h>void bubble(int a[],int len)///(int a[],int len)形参中的int a[]其实就等于int *a;即形参中的数组便是指针{    int i,j,temp;    for(i=0;i<len-1;i++)//论len-1的重要性,防止非法访问        for(j=0;j<len-1-i;j++)            if(a[j]>a[j+1])            {                temp = a[j],                a[j] = a[j+1],                a[j+1] = temp;//逗号表达式            }    for(i=0;i<len;i++)        printf("%d\t",a[i]);}int main(void){    int x[] = {12,23,44,21,3,44,45};    bubble(x,sizeof(x)/sizeof(int));    return 0;}
    }    数组与指针:{        四种等价的函数原型(在形参中出现):{            int fun(int *a,int b);            int fun(int *,int);            int fun(int a[],int b);            int fun(int [],int);        }        数组变量是特殊的指针:{            /*************形参中的数组*******************/
# include <stdio.h>void fun(int *a,int len){    printf("fun sizeof(a) = %d\n",sizeof(a));    a[0] = 1000;    *(a+1) = 2000;}int main(){    int a[5] = {1,2,3,4,5};    printf("main sizeof(a) = %d\t",sizeof(a));    fun(a,sizeof(a)/sizeof(int));    printf("run_fun:a[0] = %d\n",a[0]);    printf("run_fun:*a = %d\t*(a+1) = %d\n",*a,*(a+1));    ///对数组名同样可以当作指针操作    return  0;}/***************输出结果***********************main sizeof(a) = 20 fun sizeof(a) = 4run_fun:a[0] = 1000run_fun:*a = 1000       *(a+1) = 2000**********************************************/
        总结:{            1、方括号运算符对指针数组都可以用[]            2、数组变量是const的指针变量,不能被赋值                int a[] <==> int * const a;        }        }       }       }

//7-3多维数组

数组的引入是为了能够通过使用下标来访问数组中指定的元素,通过循环和下标就可以实现数组元素的快捷调用而有时一个下标并不能满足应用需求,需要多个下标,于是引入多维数组{    声明与使用:        声明形式:        ///类型说明 数组名[常量表达式1][常量表达式2]…[常量表达式n] = {初值表};        ///类型说明:存储类型说明符 类型修饰符 数据类型        使用:注意下标越界                   存储结构:按行存储,连续存放          初始化:按行存储,连续存放,用大括号分隔增强可读性}

//7-4字符数组

简单介绍:{    字符数组是数组元素的数据类型都是char或wchar_t的一维数组    ///即:字符数组是C语言用来存放字符串(字符序列)的工具,并在末尾放一个“\0”作为字符串的终结    ///因此:字符串长度 = 字符串的存储长度 - 1;}字符数组的初始化:{    char str[] = "this is a C program!";//数组长度自动为21    ///也可以这样,但不方便:    char str[30] = "this is a C program!";//总不能每次都要数一下字符串有多么长吧    char str[30] = {'t','h','i','s',' ',……,'a','m','!','\0'}//太麻烦啦!!!!}常用的字符串处理函数:{    1、求给定字符串的长度
int strlen(char s[])            {                int j = 0;                while(s[i] != '\0')                    j++;                return j;            }
    2、将一个字符串复制到另一个字符串
void stpcpy(char s1[],char s2[]){    int j = 0;    while(s1[j] = s2[j++]);}
    3、比较两个字符串
int strcmp(char s1[],char s2[]){    int j = 0;    while(s1[j]==s2[j]&&s1[j]!=0)        j++;    return s1[j]-s2[j];}
    4、判断是否为原字符串的子串
int strstr(char s1[],char s2[]){    int j=0,k;    while(s1[j] != '\0')    {        if(s1[j] == s2[0])        {            k=1;//            while(s1[j+k]==s2[k] && s2[k]!='\0')                k++;            if(k == strlen(s2))                return j;        }        j++;    }    return -1;}
    5、删除字符串首尾空白字符
int strdel(char s[]){    int i=0,j=0;    int l = strlen(s)-1; //由于'\0'和s[0]的存在    while(s[i]=='\n'||s[i]=='\t'||s[i]==' ')        i++;    while(s[len-j]=='\n'||s[len-j]=='\t'||s[len-j]==' ')        j++;    s[len-j] = '\0';    strcpy(s,s+i);    return strlen(s);//返回删掉之后的字符串的长度}
    6、删除字符串中的所有某个给定字符
void del_ch(char s[],char ch){    int i=0,k=0;    while(s[i] != '\0')    {        if(ch != s[i])            s[k++] = s[i];        i++;    }    s[k] = '\0';}
    7、令一个字符串反转
void reverse(char s[]){    int j,k,temp;    for(j=0,k=strlen(s)-1;j<k;j++,k--)    temp=s[j],s[j]=s[k],s[k]=temp;}
    8、将两个字符串连接
char * strcat(char t[],char s[]){    int j=0,k=0;    while(t[j++] != '\0');    j--;    while((t[j++]=s[k++]));    return t;}
}数字串与数值之间转换的函数{    1、将十进制字符串转化成对应的整数
# define BASE 10int atoi(char s[]){    int j, sum = 0;    for(j=0;s[j]!='\0';j++)        num = num*BASE + s[j] - '\0';    return num;}
    2、将一个基数为BASE的整数转换成数字串
void itoa(int n,char s[]){    int sign, j=0;    if( (sign=n)<0 )        n = -n;    while(n>0)    {        s[j++] = n%BASE + '0';        n/=BASE;    }    if(sign<0)        s[j++] = '-';    s[j] = '\0';    reverse(s);}
}二维字符数组{    初始化:        char s[2][5] = {"one","two"};    使用:        某一行的首地址为:            数组名[该行下标]   //即:&数组名[该行下标][0]}

//7-5数组的应用

矩阵乘法运算{
# include <stdio.h># define L 3# define M 4# define N 5void mul_matrix(int a[][M],int b[][N],int result[][N],int l,int m,int n){    int i,j,k,sum = 0;    for(i=0;i<l;i++)        for(j=0;j<n;j++)        {            for(k=0;k<m;k++)                sum += a[i][k]*b[k][j];            result[i][j] = sum;        }}int main(){    int a[L][M] = {{1,2,3,4},{1,2,3,4},{1,2,3,4}};    int b[M][N] = {{1,2,3,4,5},{1,2,3,4,5},{1,2,3,4,5},{1,2,3,4,5}};    int c[L][N];    int i,j;    mul_matrix(a,b,c,L,M,N);    for(i=0;i<L;i++)    {        for(j=0;j<N;j++)            printf("%5d",c[i][j]);        printf("\n");    }    return 0;}
}基于分治策略的二分查找函数{
# include <stdio.h>int Binary_Search(int a[],int search_aim,int num){    int front = 0,back = num-1,middle;    while(front <= back)    {        middle = (front + back)/2;        if(search_aim < a[middle])            back = middle-1;        else if(search_aim > a[middle])            front = middle+1;        else            return middle;    }    return -1;}int main(){    int aim = 9;    int index;    int a[] = {1,2,3,4,5,6,7,8,9,12,23};//必须是按升序排列    index = Binary_Search( a, aim, sizeof(a)/sizeof(int));    if(index != -1)        printf("find %d,and the address is %d\n",aim,index+1);    else        printf("not find!!!\n");    return 0;}
}逆波兰表达式的生成{}利用值栈对逆波兰表达式进行求值{}
0 0
原创粉丝点击