前言:
今天看官们对“c定义array”大约比较关切,同学们都需要知道一些“c定义array”的相关资讯。那么小编也在网上网罗了一些对于“c定义array””的相关知识,希望各位老铁们能喜欢,同学们快快来学习一下吧!数组(Array)是一种复合数据类型,它由一系列相同类型的元素组成。例如定义一个由4个int型元素组成的数组count:
int count[4];
和结构体成员类似,数组count的4个元素的存储空间也是相邻的。结构体成员可以是基本数据类型,也可以是复合数据类型,数组中的元素也是如此。根据组合类型,我们可以定义一个由4个结构体元素组成的数组:
struct complex_struct{ double a; double b;} a[4];
也可以定义一个包含数组成员的结构体:
struct complex_struct{ double a; double b; int count[4]} s;
数组类型的长度应该用一个整数常量表达式来指定,数组中的元素通过下标(index)来访问。
整个数组占了4个int型的存储单元,存储单元用小方框表示,里面的数字是存储在这个单元中的数据,而框外面的数字是下标,这四个单元分别用count[0], count[1], count[2], count[3]来访问。注意,在定义数组int count[4]; 方括号中的数字4表示数组的长度,而在访问数组时,方括号中的数字表示访问数组的第几个元素。数组元素是从"第0个"开始数的,这样规定使得访问数组元素非常方便,比如count数组中的每个元素占4个字节,则count[i]表示从数组开头跳过4*i个字节之后的那个存储单元。这种数组下标的表达式不仅可以表示存储单元中的值,也可以表示存储单元本身,也就是说可以做左值,因此以下语句都是正确的:
#include <stdio.h>int main(void){ int count[4] = {1, 2, 3, 4}; printf("==>UDEBUG count[%d] = %d\n", 0, count[0]); count[0] = 11; printf("==>UDEBUG count[%d] = %d\n", 0, count[0]); count[0] = count[0]*2; printf("==>UDEBUG count[%d] = %d\n", 0, count[0]); ++count[0]; printf("==>UDEBUG count[%d] = %d\n", 0, count[0]); return 0;}
使用数组下标不能超出数组的长度范围,这一点在使用变量做数组下标时尤其要注意。C 编译器并不检查count[-1]或是count[100]这样的访问越界错误,编译时能顺利通过,所以属于运行时错误。
数组也可以像结构体一样初始化,没有赋初值的元素也是用0来初始化,例如:
int count[4] = {3, 2, };
则count[0] 等于 3, count[1] 等于2, 后面两个元素等于0。如果定义数组的同时初始化它,也可以不指定数组的长度,例如:
int count[ ] = {3, 2, 1, };
编译器会根据初始化有三个元素确定数组的长度为3。
1.定义和访问数组
#include <stdio.h>int main(void){ unsigned int i = 0; unsigned int arrayLen = 0; int count[4] = {1, 2, 3, 4}; arrayLen = sizeof(count)/sizeof(int); for (i = 0; i < arrayLen; i++) { printf("==>UDEBUG count[%d] = %d\n", i, count[i]); } return 0;}
数组和结构体虽然有很多相似之处,但也有一个显著的不同:数组不能相互赋值或初始化。例如这样是错的:
int a[5] = {4, 3, 2, 1};int b[5] = a;
2.数组应用实例:统计随机数
C 标准库中生成伪随机数的是rand函数,使用这个函数需要包含头文件stdlib.h, 它没有参数,返回值是一个介于0和RAND_MAX之间的接近均匀分布的整数。RAND_MAX是该头文件中定义的一个常量,在不同的平台上有不同的取值,但可以肯定它是一个非常大的整数。通常我们用到的随机数是限定在某个范围之中的,例如0~9,而不是0~RAND_MAX。
#include <stdio.h>#include <stdlib.h>#define N 20int a[N];void gen_random(int upper_bound){ int i = 0; for (i = 0; i < N; i++) { a[i] = rand() % upper_bound; }}void print_random(){ int i = 0; for (i = 0; i < N; i++) { printf("%d ", a[i]); } printf("\n");}int main(void){ gen_random(10); print_random(); return 0;}
用#define 定义一个常量,实际上编译的工作分为两个阶段,先是预处理阶段,然后才是编译阶段。预处理做了两件事,一是把头文件stdio.h和stdlib.h在代码中展开,二是把#define 定义的标识符N 替换成20。像#include 和 #define 这种以#号开头的被称为预处理指示。define 不仅用于定义常量,也可以定义更复杂的语法结构,称为宏定义。
#include <stdio.h>#include <stdlib.h>#define N 100000int a[N];void gen_random(int upper_bound){ int i; for (i = 0; i < N; i++) { a[i] = rand() % upper_bound; }}int howmany(int value){ int count = 0; int i = 0; for (i = 0; i < N; i++) { if (a[i] == value) { ++count; } } return count;}int main(void){ int i = 0; gen_random(10); printf("value\thow many\n"); for (i = 0; i < 10; i++) { printf("%d\t%d\n", i, howmany(i)); } return 0;}
value how many0 101301 100722 99903 98424 101745 99306 100597 99548 98919 9958
从结果来看,0~9 各个数字出现的概率都在10000左右,分布比较均匀。
3.字符串
字符串可以看作一个数组,它的每个元素是字符型的,例如字符串“hello, world.\n”
注意每个字符末尾都有一个字符'\0' 做结束符,这里的\0 是ASCII码的八进制表示。数组元素可以通过数组名加下标的方式访问,而字符串字面值也可以像数组名一样使用,可以加下标访问其中的字符。
数组可以像结构体一样初始化,如果是字符数组,也可以用一个字符串字面值来初始化
char str[10] = "Hello";
char str[10] = { 'H', 'e', 'l', 'l', 'o', '\0'};
str的后四个元素没有指定,自动初始化为0,即NULL 字符。注意,虽然字符串字面值"Hello" 是只读的,但用它初始化的数组str确实可读可写的。数组str中保存了一串字符,以'\0'结尾,也可以叫字符串。
如果用于初始化的字符串字面值比数组还长,比如:
char str[10] = "Hello, world.\n";
则数组str只包含字符串的前10个字符,不包含NULL字符,这种情况编译器会给出警告,如果要用一个字符串字面值准确地初始化一个字符数组,最好的办法是不指定数组的长度,让编译器自己计算:
char str[] = "Hello, world.\n";
字符串字面值的长度包括NULL字符在内一共15个字符,编译器会确定数组str的长度为15。
使用printf加%s进行打印:
printf("string: %s\n", str);
printf 会从数组str 的开头一直打印到NULL字符为止。如果数组str 中没有NULL字符,那么printf 函数就会访问数组越界,后果可能会很出乎意料;有时候打印出乱码,有时候看起来没有错误,有时候引起程序崩溃。
标签: #c定义array