定义
1、定义格式: 数组类型 数组名[整数或整数表达式]; 例:int a[10];
在c99之前,下标只能是常量表达式,常量表达式中可以包括常量和符号常量,但不包含变量。也就是说,C语言不允许对数组的大小做动态定义,即数组的大小不依赖于程序运行过程中的变量的值。在c99之后,下标可以是整数或整数表达式。
2、错误声明类型:
下列声明是错误的:
int n; scanf("%d",&n); int a[n];//错误原因:在程序中临时输入数组的大小
float a[0]; //错误原因:数组大小为0没有意义
int b(2)(3); //错误原因:不能使用圆括号
int k =3, a[k];//错误原因:不能使用变量说明数组大小
初始化
以 int mark[100];为例:
每个元素都是整型元素,占用4字节,数组元素的引用方式是“数组名[下标]",所以访问数组mark中的元素的方式是mark[0],mark[1],mark[2]…mark[99].(数组元素是从0开始编号的)。
1.在定义数组时对数组元素赋初值。
正确:int a[10] = {0,1,2…9}; 错误:int a[10]; a[10] ={0,1,2…9};
2.可以只给一部分元素赋值。int a[10]={0,1,2,3};//此时后面6个元素值为0
3.元素值全部为0:int a[10]={0,0,0…0}; 或者 int a[10]={0};
4.不指定数组长度:int a[]={1,2,3,4,5};//此时要求具体元素已知
5.a[i + j *10] = 0;也是正确的。
6.C99以后:指定初始化式:int a[15] = {[2] = 29, [14] = 7, [9] = 48};在这一初始化方法中,【】里的数字称为指示符。赋值的顺序随意。指示符必须是整形常量表达式,如果数组的长度是省略的,指示符可以是任意非负整数,此时数组的长度=指示符的最大值。
各种数组
字符数组
1.对单个字符单独赋值进行初始化。例如:char c[10]; c[3]='m';
2.对整个数组进行初始化,例:char c[10]={'I’,‘a‘,’m’,…};
3.字符串,常用:char c[10] = "hello";
常量数组
无论是一维数组还是多维数组,都可以通过在声明的最开始处加上单词const而成为“常量”:
const char hex_chars[] = {'0', '1', '2', 'A', 'B', };
对数组使用sizeof运算符。
运算符sizeof可以确定数组的大小(字节数)。如果数组a有10个整数,那么sizeof(a)=40,一个整数占4个字节。
数组的长度=sizeof(a)/sizeof( a[0] )。【为什么这里推荐使用sizeof(a[0])而不是sizeof(数组类型)呢?因为数组类型需要到上面定义的地方去找,不如直接用a[0]来的方便)。
实例
#include<stdio.h>
#include<stdlib.h>
//在头文件<stdlib.h>中说明了用于数值转换、内存分配以及具有其他相似任务的函数。
//一维数组的传递,数组长度无法传递给子函数
//即不可以是a[],而是数组和数组长度分开传递
//C语言的函数调用方式是值传递
void print(int b[],int len)
{
//在下面的main里:print(a,5);给赋值:b=a[],len=5;
for (int i = 0; i < len; i++)
{
printf("%3d",b[i]);
}
b[4]=20;//这是后面输出:a[4] = 20的原因。
printf("\n");
}
//数组越界
//一维数组的传递
#define N 5;
int main()
{
int j = 10;
int a[5] = {1,2,3,4,5};
int i = 3;
//看看越界访问的后果
a[5] = 10;
a[6] = 21;
a[7] = 22;
print(a,5);//调用函数print
printf("a[4] = %d\n",a[4]);//注意看a[4]的值,已经发生了变化。
}
输出结果:
text.c:28:2: warning: array index 5 is past the end of the array (which contains 5 elements) [-Warray-bounds]
a[5] = 10;
^ ~
text.c:24:2: note: array 'a' declared here
int a[5] = {1,2,3,4,5};
^
text.c:29:2: warning: array index 6 is past the end of the array (which contains 5 elements) [-Warray-bounds]
a[6] = 21;
^ ~
text.c:24:2: note: array 'a' declared here
int a[5] = {1,2,3,4,5};
^
text.c:30:2: warning: array index 7 is past the end of the array (which contains 5 elements) [-Warray-bounds]
a[7] = 22;
^ ~
text.c:24:2: note: array 'a' declared here
int a[5] = {1,2,3,4,5};
^
3 warnings generated.
1 2 3 4 5
a[4] = 20
Abort trap: 6
检查数中重复出现的数字
#include <stdio.h>
//检查数中重复出现的数字
/*
用来检查数中是否有出现多于一次的数字。
例如:输入28212,这里面就有一个重复的数字——2,此时输出:Repeated dight
实现原理:定义一个名叫dight_seen的数字,假设数组为bool型的,现在假设每一个元素都是0.
依次检查一个n中的数字,并将数字存储在dight变量中。
将dight作为数组dight_seen的下标,然后设置dight_seen[dight] = 1。
所以再次出现该数字时,数组[该数字=1],证明之前存过这个数字,再次存储,是重复的。
*/
#include <stdbool.h>
int main(void)
{
bool dight_seen[10] = {false};
int dight;
long n;
printf("Enter a number: ");
scanf("%ld",&n);
while (n > 0)
{
dight = n % 10 ;
if (dight_seen[dight])
{
break;
}
dight_seen[dight] = true;
n /= 10;
}
if (n > 0)
{
printf("Repeated dight \n");
}
else
{
printf("No repeated dight\n");
}
return 0;
}
未完成的程序:
1,修改上面的程序,使其可以显示出哪些数字是重复的。
Enter a number: 939577
Repeated digit(s): 7 9
2,继续修改上面的程序 ,使其打印出一份列表,显示出每个数字在数中出现的次数:
Enter a number: 41271092
Digit: 0 1 2 3 4 5 6 7 8 9
Occurrences: 1 2 2 0 1 0 0 1 0 1
3,编写程序读取一个5×5的整数数组,然后显示出每行的和与每列的和。
Enter row 1: 8 3 9 0 10
Enter row 2: 3 5 17 1 1
Enter row 3: 2 8 6 23 1
Enter row 4: 15 7 3 2 9
Enter row 5: 6 14 2 6 0
Row totals: 30 27 40 36 28
Column totals: 34 37 37 32 21
4,编写程序,生成一种贯穿10×10字符数组(初始时全为字符’.')的“随机步法”。程序必须随机地从一个元素 “走到”另一个元素,每次都向上、向下、向左或向右移动一个元素位置。已访问过的元素按访问顺序用字母A 到Z 进行标记。下面是一个输出示例:
5,已知的最古老的一种加密技术是凯撒加密(得名于Julius Caesar)。该方法把一条消息中的每个字母用字母表中固定距离之后的那个字母来替代。(如果越过了字母Z,会绕回到字母表的起始位置。例如,如果每个字母都用字母表中两个位置之后的字母代替,那么 就被替换为 , 就被替换为 。)编写程序用凯撒加密方法对消息进行加密。用户输入待加密的消息和移位计数(字母移动的位置数目):
Enter message to be encrypted: Go ahead, make my day.
Enter shift amount (1-25): 3
Encrypted message: Jr dkhdg, pdnh pb gdb.
注意,当用户输入26与移位计数的差值时,程序可以对消息进行解密:
Enter message to be encrypted: Jr dkhdg, pdnh pb gdb.
Enter shift amount (1-25): 23
Encrypted message: Go ahead, make my day.
可以假定消息的长度不超过80个字符。不是字母的那些字符不要改动。此外,加密时不要改变字母的大小写。提示 :为了解决前面提到的绕回问题,可以用表达式((ch - ‘A’) + n) % 26 + 'A’计算大写字母的密码,其中ch 存储字母,n 存储移位计数。(小写字母也需要一个类似的表达式。)
6,
编写程序打印 的幻方( 的方阵排列,且每行、每列和每条对角线上的和都相等)。由用户指定 的值:
This program creates a magic square of a specified size.
The size must be an odd number between 1 and 99.
Enter size of magic square: 5
17 24 1 8 15
23 5 7 14 16
4 6 13 20 22
10 12 19 21 3
11 18 25 2 9
把幻方存储在一个二维数组中。起始时把数1放在0行的中间,剩下的数 依次向上移动一行并向右移动一列。当可能越过数组边界时需要“绕回”到数组的另一端。例如,如果需要把下一个数放到-1行,我们就将其存储到 行(最后一行);如果需要把下一个数放到 列,我们就将其存储到0列。如果某个特定的数组元素已被占用,那就把该数存储在前一个数的正下方。如果你的编译器支持变长数组,声明数组有 行 列,否则声明数组有99行99列。
7,发牌