C语言学习笔记_数组

第七章数组

*****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) = 4
run_fun:a[0] = 1000
run_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 10
int 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 5
void 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;
}
}
逆波兰表达式的生成{

}
利用值栈对逆波兰表达式进行求值{

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值