C语言数组入门到精通(数组精讲)

 少一些豪情壮志的承诺,多一些脚踏实地的坚持!

目录

 1.理论理解

1.1二维数组定义:

1.2具体定义分析:

1.3解决思路:

1.3.1具体分析:

1.3.2论证说明 

1.3.3具体分析

1.4矩阵基本预算:矩阵(线性代数会学)

1.4.1转置矩阵: 

 1.4.2矩阵相加:

1.4.3矩阵相乘: 

 2.代码演示详解:

2.1二维数组基本定义和使用方式

 2.2典型应用案例冒泡排序:

2.3二维数组案例程序编译讲解:

案例1:二维数组行列交换

案例2:求二维数组中最大值且输出对应行号

案例3:扩展补充

2.4字符数组分类代码详解:

2.4.1字符数组的定义、使用:

2.4.2字符数组初始化

2.4.3字符数组:strcpy、strcmp、strcat函数应用具体案例详解

2.4.5字符数组:puts、fputs函数具体应用代码案例:

2.4.6字符数组 :scanf、gets、fgets函数应用案例代码详解:

2.4.7综合应用代码详解:


 1.理论理解

1.1二维数组定义:

C语言数组入门到精通(数组精讲)_第1张图片

二维数组基本形式

      二维数组本质上是以数组作为数组元素的数组,即"数组的数组",类型说明符 数组名[常量表达式][常量表达式]。二维数组又称为矩阵,行列数相等的矩阵称为方阵。对称矩阵a[i][j] = a[j][i],对角矩阵:n阶方阵主对角线外都是零元素。

1.2具体定义分析:

int a[3][4];

二维数组—(可以理解成:矩阵)

a[0][0

a[1][0 a[2][0]
a[0][1] a[1][1] a[2][1]
a[0][2] a[1][2] a[2][2]
a[0][3] a[1][3] a[2][3]

       一个3行,4列的二维数组。其行号: 0,1,2;其列号: 0,1,2,3最大下标的元素为 a[2][3],没有 a[3][4]这个元素数组共有3行,每一行都是:4个元素的一维数组,每一行的数组名分别为: a[0],a[1],a[2]从整体看,任何一个二维数组都可以看成是一个一维数组,只不过其数组元素又是一个一维数组。
二维数组定义同时若有初始化,可以省略行号不写:如int al[31={1.2.3.4.5.6}系统会按照数据的个数,和规定的列数,来确定数据分几行?
       二维数组定义同时若有初始化,可以省略行号不写,但列号不能省略 :如 int a[3][]={1,2,3,4,5}系统无法按照数据的个数,和规定的行数,来确定数据分几列。 

1.3解决思路:

解题顺口溜:“1定2列3编写”

定义位置行列、数组、数组边界确定

列表说明,考虑scanf、gets函数用法细节(后文有典型案例介绍)

编写程序定义不能重复命名,注意合法性。

1.3.1具体分析:

二维数组的首元素,第二个元素,第三个元素........表示什么?

a[0]、a[1]、a[2]又各自代表什么,有几层含义,为什么有多层含义?

分析思路:

等号左边:a是什么?那a + i呢(为什么)?跟二维数组的元素定义有关

等号右边:a[i]代表的含义

1.3.2论证说明 

int a[3][4]= { 1,3,5,7,9,11,13,15 17,19,21,23 };

a                                                    二维数组名,指向一维数组a[0],即0行地址

a[],*(a+0),*a                                        0行0列元素的地址

a+1,&a[1]                                            第1行首地址

a[1],*(a+1)                                          a[1][0]的地址

a[1]+2,*(a+1)+2,&a[1][2]                             a[1][2]的地址

*(a[1]+2),*(*(a+1)+2),a[1][2]                     a[1][2]的值

1.3.3具体分析

C语言数组入门到精通(数组精讲)_第2张图片

1.4矩阵基本运算:

矩阵(线性代数)

1.4.1转置矩阵: 

//其中A, B是m*n矩阵:

void tramat(matrix A,matrix B){ int i,j;

for(i=0; i

 1.4.2矩阵相加:

//其中A,B,C是m*n矩阵:

void addmat(matrix C, matrix A, matrix B){

int i, j;

for(i=0; i

1.4.3矩阵相乘: 

//其中A是m*n矩阵,B是n*1矩阵,C为m*1矩阵

void mutmat(matrix C, matrix A, matrix B){

int i, j, k;

for(i=0; i

 原理是支持实际编程的思想,需要巩固了解。推荐了解:线性代数、离散数学

 2.代码演示详解:

2.1二维数组基本定义和使用方式

#include 
#include 
/*
   二维数组的定义和使用:
     1.定义:格式:类型符  数组名[常量][常量],
     第一个方括号表示行,第二个方括号表示列。)
     2.二维数组结构:逻辑结构是二维数组,等效于我们见到的表格,
     但是实际上内存中没有多维,所以实际上存放的依旧是线性结构,存放方式是按行存放。
     3.二维数组注意事项:
     1)数组中没有a[3][x],也没有a[x][4]
     2)访问数组不要越界


//(举例3行4列

     int a[3][4];
   int i,j;
   int num=0;
   for(i=0;i<3;i++){
       for(j=0;j<4;j++){
           a[i][j]=num;
           num++;
       }
   }
 for(i=0;i<3;i++){
       for(j=0;j<4;j++){
        printf("%d ",a[i][j]);
       }
       printf("\n");
   }

}
   */

int main()
{
    //二维数组初始化
    // 1.分行初始化
    int a1[3][4] = {
        {0, 1, 2, 3},
        {4, 5, 6, 7},
        {8, 9, 10, 11}};
    // 2.将数组元素全部写在{}内,依次赋值
    int a2[3][4] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
    // 3.可以向二维数组进行局部编译初始化
    //如果对应位置有值就赋值,没有就系统默认赋值为:0
    //如果对二维数组全部元素赋初值,第一个[]可以省略不写,第二个[]一定不能省略

    int a3[3][4] = {
        {1},
        {5},
        {9}};
    int i, j;

    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 4; j++)
        {
            printf("%d ", a3[i][j]);
        }
        printf("\n");
    }
}

 2.2典型应用案例冒泡排序:

#include 
#include 
/*
   冒泡排序

   实现数组:
int a[6] = {5,3,6,2,9,10}

*/

int main()
{

    int a[6] = {5,3,6,2,10,8};
    int i;
    //int n= sizeof(a)/sizeof(int);
    int j;
    for(i=0; i<6-1; i++)
    {
        for(j=0; j<6-1-i; j++)
        {
            //元素交换前提挨着的两个数,前者比后者大/
            if(a[j]>a[j+1])
            {

                int tmp;
                tmp = a[j];
                a[j] = a[j+1];
                a[j+1] = tmp;

            }

        }

    }
    for(i=0; i<6; i++)
    {

        printf("%d \n", a[i]);

    }
}

2.3二维数组案例程序编译讲解:

案例1:二维数组行列交换

案例2:求二维数组中最大值且输出对应行号

案例3:扩展补充

#include 
int main()
{

    /*
    1.问题1:实现二维数组进行列交换
    1 2 3    1 4
    4 5 6    2 5
             3 6
    解决问题关键就是:
    a[i][j] a [j][i]
    i=0,j=1


//解题代码如下:
   int a[2][3] = {
        {1, 2, 3},
        {4, 5, 6}};
    int b[3][2];
    int i, j;
    //将2行3列改成3行2列
    for (i = 0; i < 2; i++)
    {
        for (j = 0; j < 3; j++)
        {
            b[j][i] = a[i][j]; //交换
        }
    }
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 2; j++)
        {
            printf("%d ", b[i][j]);
        }
        printf("\n");
    }



     2.问题2:求二位数组,中最大元素的值,并输出它的行列号
     //解题代码:
     int a[3][4] = {
        {5, 1, 3, 7},
        {2, 4, 6, 8},
        {9, 10, 11, 12}};
    //定义行号列号
    int row;
    int column;
    //定义擂主
    int max = a[0][0];
    // 2.依次比武
    int i, j;
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 4; j++)
        {
            if (a[i][j] > max)
            {
                max = a[i][j];
                row = i;
                column = j;
            }
        }
    }
    printf("max=%d,row=%d,column=%d\n", max, row, column);

     补充内容:
     2)二维数组的数组名
     和一维数组类似,数组名都是常量,不可以赋值
     可以使用sizeof(数组名)计算数组总大小

    */
    int a[5][10];
    printf("sizeof(a)=%d\n", sizeof(a));
    // 5个int组成,所以总大小=5*4*10=200
    printf("sizeof(a[0]=%d\n)", sizeof(a[0]));
    // a[0][0],因为int占4个字节
    printf("sizeof(a[0][0]=%d\n)", sizeof(a[0][0]));
    //求二维数组的行数
    printf("二维数组行数:%d\n", sizeof(a) / sizeof(a[0]));
    //求列数;思路:
    printf("二维数组的列数:%d\n", sizeof(a[0]) / sizeof(a[0][0]));
    //求行*列
    printf("二维数组行列总数为:%d\n", sizeof(a) / sizeof(a[0][0]));
}

/*
多维数组:
二维以上就是多维数组
例如:
int a[3][4][5] = {
    {},
    {},
    {}
}

*/

2.4字符数组分类代码详解:

2.4.1字符数组的定义、使用:

#include 
/*
字符数组的定义与使用
1.定义格式
char数组名[常量表达式]
2.C语言中没有字符串类型,字符串是存储在字符数组中
3.字符串和字符数组的关系:
    字符串是以'\0'或者0结尾的就是字符串(asscel码 \0=0 )
    字符串一定是字符数组,而字符数组不一定是字符串
    //字符串输出:printf("%s\n")百分号s


*/
int main()
{
    char a[10];
    //定义一个字符串
    char a1[10] = {'h', 'e', 'l', 'l', 'o', '\0'}; //表示字符串hello
    char a2[10] = {'h', 'e', 'l', 'l', 'o', 0};    //也表示字符串hello
    char a3[10] = {'h', 'e', 'l', 'l', 'o'};       //表示字符数组
    char a4[] = "hao";//h a o \0(系统会自动加上\0结束符,所以输出占了4个字节)
    //\0后面尽量不要加数字;   字符串
    char a5[] = "\012hao";
    printf("a1=%s\n", a1);
    printf("a2=%s\n", a2);
    printf("a3=%s\n", a3);
    printf("a4=%s\n", a4);
    printf("a5=%s\n", a5);
    printf("sizeof(a1)=%d\n", sizeof(a1));
    printf("sizeof(a4)=%d\n", sizeof(a4));
    printf("sizeof(a5)=%d\n", sizeof(a5));
    return 0;
}

2.4.2字符数组初始化

#include 
int main()
{

    /*
    字符数组初始化?

    说明?
    1.输出字符串是不包括结束符\0
    2.使用%s输出时printf后面的输出项是数组名,而不是数组元素?
    3.如果数组长度>实际字符串长度,也只输出到\0就结束?

    
    */
char a1[10] = {'h', 'a', 'o'}; //定义一个一维数组,这是字符数组
    char a2[8] = {'h', 'a', 'o'};  //定义一个一维数组,这是字符数组
    char a3[] = "hao";             //只是一个字符串
    int i;
    for (i = 0; i < 10; i++)
    {
        printf("%C ", a1[i]);
    }
    printf("\n");
    printf("a2=%s ", a2);
    printf("\n");
    printf("a3=%s", a3);
    printf("\n");
    printf("sizeof(a1)=%d", sizeof(a1));
    printf("\n");
    printf("sizeof(a2)=%d", sizeof(a2));
   
}

2.4.3字符数组:strcpy、strcmp、strcat函数应用具体案例详解

#include 

/*
strcpy函数
1)一般形式:
char *strcpy(char *dest,char * src);
    char *dest —— 目标数组名
    char * src —— 原数组名
    2)功能
      将src所指向的字符串拷贝至dest中,'\0'也会拷贝过来
      拷贝的原理:从首元素开始到"\0"结束
   // 解决代码
char src[100]="hello word";
int dest [100];
strcpy(dest,src);
printf("%s\n",dest);
printf("%d\n",sizeof(dest));

    //strncpy函数
    1)一般形式:
 char *strncpy(char *dest,char * src,size_t n);
    char *dest —— 目标数组名
    char * src —— 原数组名
    size_t n ——— 前n个
    2)功能
     将src所指向的字符串的前n个字符串拷贝至dest中,
     是否拷贝到"\0"看指定的长度是否包含'\0'决定。


   //strcmp函数
    1)一般形式:
 char *strcmp(const char  *sl,const char *s2);
    char  *sl —— 数组名
    char *s2 —— 数组名2
    size_t n ——— 前n个
    2)功能
     比较s1和s2的大小,实际上比较的是字符的ASCII
    3) 注意事项:
     比较的不是长度,也就是不是谁长谁大,比如:abc>Abcd
     按元素一次比较,如果相等比较下一个元素

     //解决代码:
     char s1[] = "abc";
    char s2[] = "abcd";
    int result = strcmp(s1, s2);
    if (result > 0)
    {
        printf("%s>%s", s1, s2);
    }
    else if (result < 0)
    {
        printf("%s<%s", s1, s2);
    }
    else
    {
        printf("%s=%s", s1, s2);
    }


 // strcat函数
    1)一般形式:
    char strcat(char *dest,char,size_t n)
    2)功能:
    将src字符追加至dest尾部,'\0'结束符也会追加过去
    strncat
    1)一般形式:
    char strncat(char *dest,char,size_t n)
    2)功能:
    将src字符串前n个字符追加至dest尾部,'\0'结束符也会追加过去
*/
int main()
{
    char src[] = "hello word";
    char dest[] = "China";
    //strcat (dest,src);//字串的拼接
   strncat  (dest, src,sizeof("hello")+1);
    
        printf("dest=%s\n", dest);
    

    return 0;
}

2.4.5字符数组:puts、fputs函数具体应用代码案例:

#include 
/*
puts函数
1)一般形式:
int puts(const char *s)
char *s——就是数组名
2)功能
就是向屏幕输出字符串,输出字符串末尾自动加上\n
3)注意事项:
puts只是在输出到屏幕时加了\n,但字符串本身并没有变化
//解决代码:
char str[10] = "China";
   puts (str);
   printf("str = %s",str);

fputs函数
1)一般形式:
int  fputs(const char *str,FILE *stream)
 char *str——就是数组名
 FILE *stream ——stdout
2)注意事项:
不会默认加上换行符
如果输出到屏幕,stream固定写为stdout
//解决代码
char str[] = "China";
    fputs(str, stdout);
    return 0;


    //strlen函数
   一般形式:size-t strlen(const char*s)
   char *str——就是数组名
   size-t:函数返回值
   2)功能:
   计算指定字符串的长度,不包括结束符"\0";
   原理:从首元素到结束符'\0'但是不包括结束符'\0'
*/

int main()
{
    char str[] = "China";
    char str2[] = "\0China"; //当检测到有\0字符,就会自动跳出,结束符所以最后输出的值为:0
    char str3[] = "China";
    //如果[]里面定义的字符个数,那么后面跟的具体值如果超过了给个字符限制,超过部分将不会输出
    //例如:运行前需要把其他的定义数值给注释掉,不然会引起冲突
    char str4[5] = "chinese";
    // int len = strlen(str4);//这个定义为测试超过给定的字符长度而使用
    int len = strlen(str);
    printf("len(str)=%d\n", len);

    len = strlen(str2);
    printf("len(str2)=%d\n", len); // 0
    // sizeof计算的是数据类型的长度, 不会因为结束符而结束
    printf("sizeof(str2=%d\n", sizeof(str2)); //结果:sizeof(str2=7,7个字符

    len = strlen(str3);
    printf("len(str3)=%d\n", len); // 0
    // sizeof函数会输出字符数,在计算机内存中,保存形式为:China\0, 因此会算上\0所占字符,所以最后输出的字符数是6 printf("sizeof(str3=%d\n", sizeof(str3));
    printf("str3=%s\n", str3);

    len = strlen(str4);
    printf("len(str4)=%d\n", len);
    printf("sizeof(str4=%d\n", sizeof(str4));
    // printf("str4=%s\n", str4);//这一个为测试超过给的定的字符长度使用
    return 0;
}

2.4.6字符数组 :scanf、gets、fgets函数应用案例代码详解:

#include 
int main()
{
    /*
    1.scanf 和 gets对比分析

    // scanf缺点:不会自动检测字符串是否越界,不同编译器会产生错误。
    //为了避免可使用gets函数
    //1.1案例程序scanf的使用:
    char str[100]; //如果没有对字符数组进行初始化?
    printf("请输入字符串str:");
    scanf("%s", str); //不要家取地址符&,直接写数组名
    printf("str=%s", str);
    printf("\n");
    char tmp[100];
    printf("请输入字符串tmp:");
    scanf("%s", tmp);
    printf("tmp=%s", tmp);
    printf("\n");
    char a[100];
    printf("请输入字符串a:");
    scanf("%s", a);
    printf("a=%s", a);
    return 0;

    //字符串函数
    1.2 gets函数的使用
    1)gets的一般形式
    gets(字符数组)
    2)功能:
    从键盘中读取字符串到指定的字符数组
    3)主注意事项
    get中允许有空格,也不做越界检查,其实也不安全
//代码解决:
    char str[10];
    printf("请输入字符串:");
    gets(str);
    printf("str=%s\n", str);
    return 0;

    //gets和scanf区别
    gets是允许输入字符串中含有空格,而scanf是不允许的
    遇到换行符,或遇到文件结尾符才停止接受输入
    因此这两种不推荐使用

    //fgets函数
    1)一般形式:
    char * fgets(char *s ,int size,FILE *stream);
    char *s——就是指放数组名
    size——指的就是接受多少个字符
    FILE *stream —— stdin

    2)功能:
    //从stream中读取字符,保存到s中,直到出现换行,
    //读到文件结尾或是size-1个字符为止,最后自动加上:\0作为字符串结束符

    //注意事项:
    如果输入内容大于size-1,只取size-1;
    换行符也会读入:“\n”
    因此fgets是安全的

    */
    char str[10];
    printf("请输入字符串str: ");
    fgets(str, sizeof(str), stdin);
    printf("str=%s", str);
}
 

2.4.7综合应用代码详解:

案例1:求输入单词个数

案例2:字符串比较大小

/*#include 
int main()
{
    char str[100];
    int i;
    int num=0;//统计单词个数
    int word=0;//作为是否为新单词的标??
    printf("请输入字符:");
    gets(str);//获取用户输入的字符串并存到str
    for(i=0;str[i]!='\0';i++){
        if(str[i]==' ')word=0;
        else if(word==0){
            word=1;
            num++;
        }
    }
   print("单词的个数为%d\n",num);
    return 0;

}
//求输入的字符的单词数
char arr[100];
 int i=0;
 int num=0;
 int word=0;
  printf("请输入字符,空格前为一个单词,空格后为一个新单词:");
 gets(arr);
 for(i=0;arr[i]!='\0';i++)
 {
  if(arr[i]==' ')
  {
   word=0;
  }
  else if(word==0)
  {
   word=1;
   num++;
  }
 }
 printf("这句话里有%d个单词\n",num);
*/
#include 
/*
   三个字符串中比较大小,s1 s2 s3
*/
int main()
{
    char str[3][10]; //定义一个二维数组,每一行都是一个字符串
    char tmp[10];    //存放最大的哪个字符串
    int i;
    for (i = 0; i < 3; i++){
        gets(str[i]); //读入三个字符,依次赋值给str[0],str[1],str[2]
    }
    //接下来两两比较
    if (strcmp(str[0], str[1]) > 0) {
        // str[0]大
        strcpy(tmp, str[0]); //将str[0]拷贝至tmp里面
    }
    else {
        // str[1]大
        strcpy(tmp, str[1]);
    }
    if (strcmp(str[2], tmp) > 0){ 
        // str[2]大
        strcpy(tmp, str[2]);
    }
    //tmp存的就是最大字符串
    printf("最大字符串为 %s\n",tmp);


    return 0;
}

你可能感兴趣的:(C语言成长学伴,编程工具+实战开发,c语言,开发语言)