续写上一篇的数组or指针操作

C语言,同样适用if else while 这样的语法,但不同的人,就是有不同的实现方式,甚至是技巧。

eg:

 1 #include <stdio.h>
 2 #include<string.h>
 3 typedef _Bool bool;
 4 #define true 1
 5 #define false 0
 6 #define N 10
 7 bool identity_matrix(int matrix[][N])
 8 {
 9     int row, column;
10     for (row = 0; row < N; ++row)
11     {
12         for (column = 0; column < N; ++column)
13         {
14             /*如果row和column相等,它的值就为1,否则为0
15             这里还需要注意,正面不好找时,找反面,这在高中数学时就有体会了
16             如果我们要判断row和column相等的时候此时的数组值是否是1就需要判断
17             N次,而要是我们判断roe和column相等时,数组值不为1,即为0时,出现这样
18             的情况立即返回false显然更好
19             */
20             if ((row == column) != matrix[row][column])
21                 return false;
22         }
23     }
24     return true;
25 }
26 int main(void)
27 {
28     int matrix[10][10] = {
29             { 1,0,0,0,0,0,0,0,0,0 },
30             { 0,1,0,0,0,0,0,0,0,0 },
31             { 0,0,1,0,0,0,0,0,0,0 },
32             { 0,0,0,1,0,0,0,0,0,0 },
33             { 0,0,0,0,1,0,0,0,0,0 },
34             { 0,0,0,0,0,1,0,0,0,0 },
35             { 0,0,0,0,0,0,1,0,0,0 },
36             { 0,0,0,0,0,0,0,1,0,0 },
37             { 0,0,0,0,0,0,0,0,1,0 },
38             { 0,0,0,0,0,0,0,0,0,1 },
39     };
40     int ret = 0;
41     ret=identity_matrix(matrix);
42     if (ret == 1)
43     {
44         printf("单位矩阵.\n");
45     }
46     else
47     {
48         printf("非单位矩阵.\n");
49     }
50     return 0;
51 }

上面红线处的if语句,是一个值得借鉴的表达式,这也是上一篇博客所说到的,这需要平时的积累,就算都是基本语法,但不同的人能用出不一样的花样。

这个代码还有一点不足,就是如果我把数组改成matrix[10][11],其余什么也不改变,程序运行会失常(即误判,不信可以试试),作为一个专业的程序员,必须想到输入数据不符合规范的情况,我们当然知道单位矩阵必须row和column相同,但是我们设计的程序应该要能判断输入是否合法,并给予提示。在看改进代码之前,我们先得求出二维数组的维数,看下列代码:

eg1:

 1 int main(void)
 2 {
 3     int matrix[11][12] = {
 4             { 1,0,0,0,0,0,0,0,0,0 },
 5             { 0,1,0,0,0,0,0,0,0,0 },
 6             { 0,0,1,0,0,0,0,0,0,0 },
 7             { 0,0,0,1,0,0,0,0,0,0 },
 8             { 0,0,0,0,1,0,0,0,0,0 },
 9             { 0,0,0,0,0,1,0,0,0,0 },
10             { 0,0,0,0,0,0,1,0,0,0 },
11             { 0,0,0,0,0,0,0,1,0,0 },
12             { 0,0,0,0,0,0,0,0,1,0 },
13             { 0,0,0,0,0,0,0,0,0,1 },
14     };//只初始化了10*10的
15     int x, y;
16     y = sizeof(matrix[0]) / sizeof(int);//求得列数
17     x = sizeof(matrix) / sizeof(int) / y;//求得行数
18     printf("%d %d\n", x, y);
19 }

这样是可以求出二维数组各个维数的,但是,再做更改如下:

eg2:

1 int identity_matrix(int matrix[][10])
2 {
3     int x, y;
4     y = sizeof(matrix[0]) / sizeof(int);//求得列数
5     x = sizeof(matrix) /sizeof(int)/y;//求得行数
6     printf("%d %d\n", x, y);
7        。。。。。。
8       //下列代码省略
9 }

将其放在函数中时,此时数组当参数,这样会失败,注意了,此时的sizeof(matrix)为4,是一个指针的大小(我的是在X86下,指针4字节,X64下,8个字节)。这里必须要知道,编译器对数组做的退化处理,处理成指针了,那么,怎么办呢?

eg3:

 1 #include <stdio.h>
 2 #include<string.h>
 3 typedef _Bool bool;
 4 #define true 1
 5 #define false 0
 6 #define N 10
 7 bool identity_matrix(int (*matrix)[N])//二维数组退化后的形式
 8 {
 9         int row, column;
10         for (row = 0; row < N; ++row)
11         {
12             for (column = 0; column < N; ++column)
13             {
14                 if ((row == column) != matrix[row][column])
15                     return false;
16             }
17         }
18         return true;
19
20 }
21 int main(void)
22 {
23     int matrix[12][12] = {
24             { 1,0,0,0,0,0,0,0,0,0 },
25             { 0,1,0,0,0,0,0,0,0,0 },
26             { 0,0,1,0,0,0,0,0,0,0 },
27             { 0,0,0,1,0,0,0,0,0,0 },
28             { 0,0,0,0,1,0,0,0,0,0 },
29             { 0,0,0,0,0,1,0,0,0,0 },
30             { 0,0,0,0,0,0,1,0,0,0 },
31             { 0,0,0,0,0,0,0,1,0,0 },
32             { 0,0,0,0,0,0,0,0,1,0 },
33             { 0,0,0,0,0,0,0,0,0,1 },
34     };
35     int x, y;
36     y = sizeof(matrix[0]) / sizeof(int);//求得列数
37     x = sizeof(matrix) / sizeof(int) / y;//求得行数
38     int ret = 0;
39     if (x == y)
40     {
41         ret = identity_matrix(matrix);
42         if (ret == 1)
43         {
44             printf("单位矩阵.\n");
45         }
46         else
47         {
48             printf("非单位矩阵.\n");
49         }
50     }
51     else
52     {
53         printf("请给我行列相同的矩阵\n");
54     }
55     return 0;
56 }

这样改进之后,行列不同时会提示并且不执行identity_matrix函数,如果定义的数组matrix的维数超过10,例如上面的12*12的,不管你是不是单位矩阵,都将显式非单位矩阵,因为我必须要确定数组的列数,这也算是一个小bug吧,但程序员应该确保实参和形参匹配,不过C99已经支持VLA(变长数组),可以将列数用参数传递,只是因为用的vs2015,这个编译器对c99支持不够,所以不再演示,gcc是完美支持的。

时间: 2024-08-28 06:41:37

续写上一篇的数组or指针操作的相关文章

数组与指针操作

一,数组 1,const int array[5] = {0, 1, 2, 3, 4}; 2,c99新特性,可以对指定的数组的某一个元素初始化.例如:int array[10] = {1, 3, [4] = 2, 6, 7, [1] = 32};如果多次对一个元素进行初始化,取最后一次的值. 3,c不支持把数组作为一个整体来赋值,也不支持用花括号括起来的列表形式进行赋值. 4,sizeof表达式被认为是一个整数常量. 5 * 5 - 1 就是整数常量表达式. 5,变长数组int array[n]

程序猿之---C语言细节30(数组和指针操作测试题,你能全答对吗??)

主要内容:数组和指针操作测试 #include <stdio.h> int main() { int a[5] = {1,2,3,4,5}; /* 你能答对最后一条语句的输出吗?*/ int *ptr1 = (int *)(&a+1); int *ptr2 = (int *)((int)a+1);  printf("&a = %d\n",(&a)); printf("(&a+1) = %d\n",(&a+1));

数组与指针(二)

对于数组,我们最为头痛的莫过于数组与指针的关系.在我看来,想要把数组和指针的关系理解通透,关键在于理解指针的关联类型(每个指针都有一个与之关联的数据类型).因为文章的篇幅比较长,所以分成了两篇,这是第二篇(没看第一篇的可以先看这里哦,磨刀不误砍柴工,大家要有点耐心 ^ ^ )http://www.cnblogs.com/CatDrinkMilk/p/4331355.html 二维数组与指针 在C++中,其实并没有真正意义上的多维数组,所有的多维数组其本质都是数组的数组(这句话很拗口,大家要多想几

C/C++数组和指针详解

/****************************************************************/ /*            学习是合作和分享式的! /* Author:Atlas                    Email:[email protected] /*  转载请注明本文出处: *  http://blog.csdn.net/wdzxl198/article/details/9087497 /*************************

(C语言)数组与指针的区别

以前常常听过这种说法,说数组和指针这两者比较像,但是不能混淆,可是一直没能理解.刚刚在李云的<专业嵌入式软件开发>中,看了讲述数组与指针区别的一章,似乎有所领悟.本着知乎上看到的这张图,我试着将自己的理解写一些. 首先需要了解数组和指针的工作模式. 数组: char name[] = {'T', 'o', 'n', 'y', '\0'}; 此时,这个数组的地址是这样的.其中name指向数组的开头: 指针: char name[] = {'T', 'o', 'n', 'y', '\0'}; ch

数组和指针的差别

数组和指针在使用上有一些区别,主要有以下三点: int vector[5] = {1,2,3,4,5}; int *pv = vector; 1. vector[i]  生成的代码和 *(vector +  i) 生成的不一样, vector[i] 表示法生成的机器码从位置 vector 开始,移动i个位置,取出内容.而 *(vector + i) 表示法生成的机器码则是从vector开始,在地址上增加i,然后取出这个地址中的内容.尽管结果是一样的,生成的机器码却不一样. 2. sizeof 操

JAVA之旅(二十四)——I/O流,字符流,FileWriter,IOException,文件续写,FileReader,小练习

JAVA之旅(二十四)--I/O流,字符流,FileWriter,IOException,文件续写,FileReader,小练习 JAVA之旅林林总总也是写了二十多篇了,我们今天终于是接触到了I/O了.如果你初学,不懂IO流,你可以从前往后慢慢看,但是你工作了一段时间你会发现,流的使用场景以及技术点是非常的强硬的,我们势必要掌握这个知识点,如果你觉得翻阅API比较鼓噪,看视频得不到精髓,看书看不到要点,你就跟随我的JAVA之旅,一起去探索吧! 一.I/O概述 I/O全名:Input Output

小猪猪逆袭成博士之C++基础篇(四)数组、指针、vector、迭代器

小猪猪逆袭成博士之C++基础篇(四) 关键词:数组,Vector. 一.数组与指针 数组相信大家学过C语言或者其他的语言都不陌生,简单的就是同一个变量类型的一组数据.例如:int a[10],意思就是从a开始有10个连续的int大小的空间.我们还是从初始化说起. 我们以数据类型int为例,当然也可由有很多的数据类型,可以是像int,double这种,也可以是自定义的类,一般的初始化方法有: int a[10]; int a[10]={0}; int a[3]={0,1,2}; 在前面的文章中,有

续写vim,shell脚本基础编辑,read命令,if与case判断语句,文件查找方式,压缩与解压,

一. Vim续写 ?1.命令扩展模式的位置定界 ??起始位置 cmd 终止位置???Cmd:????y复制????d删除????Gu变大写????gu变小写??例如:0y$命令意味着:????0 先到行头????Y 从这里开始拷贝????$ 拷贝到本行行尾最后一个字符????Ye 从当前位置拷贝到本单词的最后一个字符 ?2.扩展命令模式:地址定界 ? ?# 具体第#行,? ?#1,#2 从开头数第#1行到第#2行? ?#1,+#2 从开头数的第#1行到从第#1行开始数的第#2行? ? ?例:2,