少一些豪情壮志的承诺,多一些脚踏实地的坚持!
目录
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综合应用代码详解:
二维数组基本形式
二维数组本质上是以数组作为数组元素的数组,即"数组的数组",类型说明符 数组名[常量表达式][常量表达式]。二维数组又称为矩阵,行列数相等的矩阵称为方阵。对称矩阵a[i][j] = a[j][i],对角矩阵:n阶方阵主对角线外都是零元素。
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定2列3编写”
定义位置行列、数组、数组边界确定
列表说明,考虑scanf、gets函数用法细节(后文有典型案例介绍)
编写程序定义不能重复命名,注意合法性。
二维数组的首元素,第二个元素,第三个元素........表示什么?
a[0]、a[1]、a[2]又各自代表什么,有几层含义,为什么有多层含义?
分析思路:
等号左边:a是什么?那a + i呢(为什么)?跟二维数组的元素定义有关
等号右边:a[i]代表的含义
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]的值
//其中A, B是m*n矩阵:
void tramat(matrix A,matrix B){ int i,j;
for(i=0; i
//其中A,B,C是m*n矩阵:
void addmat(matrix C, matrix A, matrix B){
int i, j;
for(i=0; i
//其中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
原理是支持实际编程的思想,需要巩固了解。推荐了解:线性代数、离散数学
#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");
}
}
#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]);
}
}
#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] = {
{},
{},
{}
}
*/
#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;
}
#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));
}
#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;
}
#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;
}
#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);
}
案例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;
}