Linux中求数组长度函数,LinuxC语言中的数组和rand函数和宏定义和全排列

文章目录

一、数组也是一种复合数据类型

1.数组的定义

2.数组中的元素通过下标(或者叫索引,Index) 来访问。

3.C语言中后缀运算符的优先级高于前缀运算符

4.数组下标也可以是表达式,但表达式的值必须是整型的

5.数组的初始化

6.定义和访问数组——遍历的使用

7.数组与结构体的显著区别

二、数组的应用例子:统计随机数

1.rand函数介绍

(i)预处理器的作用:

(ii)那么用 #define 定义的常量和第 3 节 “数据类型标志enum”讲的枚举常量有什么区别呢?

(iii)硬编码的含义

2.习题

三、数组的应用例子:直方图

1.直方图的含义

2.用数组的效率低与效率高的方法比较

3.习题

四、字符串

1.字符串的定义

2.字符数组可用一个字符串字面值来初始化

3. printf 函数的格式化字符串中%s 占位符的使用注意事项

五、多维数组

1.多维数组的定义

2.多维数组的初始化

3.最后,综合本章的知识,我们来写一个最简单的小游戏--剪刀石头布:

一、数组也是一种复合数据类型

1.数组的定义

(1)

df1b8ee95301d293a385cda9c8d6661f.png

说明:

和结构体成员类似,数组 count 的4个元素的存储空间也是相邻的。

结构体成员可以是基本数据类型,也可以是复合数据类型,数组中的元素也是如此。

(2)根据组合规则,我们可以定义一个由4个结构体元素组成的数组:

06b11625d6a8a0d3bce8a9eeb953342f.png

也可以定义一个包含数组成员的结构体:

4e0f45930a7a85d6b3953cb0ec4376f6.png

2.数组中的元素通过下标(或者叫索引,Index) 来访问。

(1)

b7fc12ebaed53189b63f8f62242923bd.png

f1df4576e8c27aa4d85250a29cd47695.png

3.C语言中后缀运算符的优先级高于前缀运算符

1b1456e45076f5bd35b5f8d80a0b141f.png

4.数组下标也可以是表达式,但表达式的值必须是整型的

9c01871ecec72da1991ce1474c3b7376.png

5.数组的初始化

8cff1a5cebae39798a9e9e077bca1d90.png

6.定义和访问数组——遍历的使用

b38d1114b3aeb8eaec865f9d5c5a0064.png

7.数组与结构体的显著区别

(1)显著不同在于:

69154dd5ab04353f6781f8436e2e0150.png

(2)

1c9c5f4c6c38e3db3a433e60f4152073.png

说明:

编译器也不会报错,但这样写并不是传一个数组类型参数的意思。对于数组类型有一条特殊规则:数组类型做右值使用时,自动转换成指向数组首元素的指针。 所以上面的函数调用其实是传一个指针类型的参数,而不是数组类型的参数。

接下来的几章里有的函数需要访问数组,我们就把数组定义为全局变量给函数访问。 等以后讲了指针再使用传参的办法。

这也解释了为什么数组类型不能相互赋值或初始化,例如上面提到的 a = b 这个表达式, a 和 b 都是数组类型的变量,但是 b 做右值使用,自动转换成指针类型,而左边仍然是数组类型,所以编译器报的错是 error: incompatible types in assignment 。

二、数组的应用例子:统计随机数

1.rand函数介绍

(1)

2cb7cc0de26b0cc5c5bf6f94b77a05f6.png

(2)完整的程序如下:

2ffa3a7ee3d49297430f870a720eb200.png

说明:

这里介绍一种新的语法:用 #define 定义一个常量。

实际上编译器的工作分为两个阶段,先是预处理(Preprocess) 阶段,然后才是编译阶段,

用 gcc 的 -E 选项可以看到预处理之后、编译之前的程序,例如:

612635c658a8597ec966abcefe796013.png

说明:

(i)预处理器的作用:

一是把头文件 stdio.h 和 stdlib.h 在代码中展开;

二是把 #define 定义的标识符 N 替换成它的定义20(在代码中做了三处替换,分别位于数组的定义中和两个函数中) 。

(ii)那么用 #define 定义的常量和第 3 节 “数据类型标志enum”讲的枚举常量有什么区别呢?

define 不仅用于定义常量,也可以定义更复杂的语法结构,称为宏(Macro) 定义。

define 定义是在预处理阶段处理的,而枚举是在编译阶段处理的。

8a80e6beb9f23fc4bdab8775cb404e7e.png

(3)

30376e455876be13f7e38ab4777a400f.png

毕竟我们的样本太少了,才20个数,如果样本足够多,比如说100000个数,统计一下其中每个数字出现的次数也许能说明问题。但总不能把100000个数都打印出来然后挨个去数吧?

我们需要写一个函数统计每个数字出现的次数。

完整的程序如下:

129f8538cd022f0dc848b74f63982352.png

说明:

(iii)硬编码的含义

086910076c7ac5340ca618c85c9d9a93.png

2.习题

58f5898e8e6f9751cf79cd7f617afd8c.png

56fc1759b10b60f43d89892de7aa6d34.png

三、数组的应用例子:直方图

1.直方图的含义

7eb3266edc7da5e84c0246e09b0ffcfc.png

2.用数组的效率低与效率高的方法比较

(1)效率低的方法:

648f1fb49a71f4495d839ca7579a2552.png

说明:

(a)

f45790415dd1a78a6693c60fa7d9508d.png

(b)尽管上面的方法可以准确地得到统计结果,但是效率很低,这100000个随机数需要从头到尾检查十遍,每一遍检查只统计一种数字的出现次数。

(2)效率高的方法

866380c4d9f352d6c0ffa7284f02f1da.png

说明:

3d8cac03b1191fd1a790dbda971a67d9.png

659bff87fece23dd292cf3213c95fabb.png

3.习题

accbadb798cac2d5667484b2326e3e10.png

int main(void)

{

int i,histogram[10]={0};

gen_random(10);

for(i=0;i

cbaac4cc33fa046874e302f815bcfa8b.png

0d13dd94d74cb81113776859270bb460.png

如果还不懂的话:

参考:https://blog.csdn.net/qq_33724710/article/details/50924097(有输出结果)

参考:https://blog.csdn.net/sunbingxi_/article/details/6125426(感觉是元老级答案)

参考:https://segmentfault.com/a/1190000000725176(答案都有,但不完全对)

第一个问题的答案如下:

void prem(int offset);

void print();

void pozition(int i,int offset);

#define N 3

int a[N]={0};

int main(void)

{

int i;

for(i=0;i

第二个问题的答案如下:

需要改动的地方有:

#define N 3

#define M 2

void prem(int offset)

{

if(offset==M-1)

{

print();

return;/* 每次输出以后,return到main函数,使得offset=0*/

}

else

{

for(int i=offset;i

第三个问题的答案:

假设有一个两两元素互不相同的N长数组a,从数组尾端依次取M个数。

数组b[]得重新定义。

void comb(int n, int m)

{

int i;

if (m == 0) {

print();

return;

} else {

for (int i = n-1; i >= 0; --i)

{

b[m-1] = a[i];

comb(i, m-1);

}

}

}

四、字符串

1.字符串的定义

(1)字符串可以看作一个数组,它的每个元素是字符型的。

例如字符串 “Hello, world.\n” 图示如下:

f654e7a62237f4aa17d9d5c1f9d19efe.png

注意每个字符末尾都有一个字符 ‘\0’ 做结束符,这里的 \0 是ASCII码的八进制表示,也就

是ASCII码为0的Null字符,在C语言中这种字符串也称为以零结尾的字符串(Null-terminated String)。

(2)数组元素可以通过数组名加下标的方式访问,而字符串字面值也可以像数组名一样

使用,可以加下标访问其中的字符:

704158ab317355178290808ed3b05e91.png

2.字符数组可用一个字符串字面值来初始化

0e15bbcfac35be919bd6b34a4d74a446.png

(1)str 的后四个元素没有指定,自动初始化为0,即Null字符.。

(2)在本书中只要是以Null字符结尾的一串字符都叫字符串,不管是像 str 这样的数组,还是像 “Hello” 这样的字符串字面值。

(3)如果用于初始化的字符串字面值比数组还长,eg:

1b8a917844b752688ebea6ce9fad4643.png

则数组 str 只包含字符串的前10个字符,不包含Null字符,这种情况编译器会给出警告。

(4)如果要用一个字符串字面值准确地初始化一个字符数组,最好的办法是不指定数组的长度,让编译器自己计算:

fd774293f8a3e9232dcc49a34c205474.png

(5)有一种情况需要特别注意,如果用于初始化的字符串字面值比数组刚好长出一个Null字符的长度(打印字符串可能会出错)

22e2175f205d7d207ffa3f2e26002012.png

3. printf 函数的格式化字符串中%s 占位符的使用注意事项

626dc124413d251ae75fe1c27af46882.png

五、多维数组

1.多维数组的定义

(1)一个数组的元素可以是另外一个数组,这样就构成了多维数组(Multi-dimensional Array) 。例如定义并初始化一个二维数组:

cea8d1c7be5bdee2ba965fbf3bb2086e.png

(2)从概念模型和物理模型上去理解多维数组 (从物理模型上去理解,是真的爽)

b930de6decaaa71ab73492645168cbc9.png

2.多维数组的初始化

(1)多维数组的初始化

cfe49ed640df52329a848cb24201763f.png

(2)如果是多维字符数组,也可以嵌套使用字符串字面值做Initializer

a9af0d8f70b522e8bea408a575dbfe7d.png

多维字符数组的解释如下:

bc57fa7a7b976c68574bc7da1711d423.png

3.最后,综合本章的知识,我们来写一个最简单的小游戏--剪刀石头布:

(1)代码如下

3cfb9bd3d5ec0fe7446321140d7d6363.png

解释如下:

1ab9535e1caab1eaec55eed8f7d3e02f.png

(2)练习

3d0cff0c4d0187c238680beaa598058e.png

胜 负 平 胜 负

man-computer: -2 -1 0 1 2

man-computer+4: 4 2 3 4 5 6

(man-computer+4)%: 3 2 0 1 2 0

(man-computer+4)%3-1: 1 -1 0 1 -1

剪刀石头布相生相克,形成一个环,凡是具有环的特性的数学模型都可以考虑用取模运算, 首先确定了man-computer和%3,然后再调整其它常数得到normalized的结果。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值