数组
一维数组
如何定义
类型符 数组名[常量表达式];
- 数组名的命名规则和变量名相同,遵循标识符命名规则。
- 常量表达式中可以包括常量和符号常量,如“int a[3+5]”是合法的。不能包含变量,如“int a[n]”是不合法的。
引用数组元素
数组名[下标]
例如,a[0]就是数组a中序号为0的元素,它和一个简单变量的地位和作用相似。
初始化
-
在定义数组时对全部数组元素赋予初值
int a[10] = {0,1,2,3,4,5,6,7,8,9,};
-
可以只给数组中的一部分元素赋值
int a[10] = {0,1,2,3,4}; //表面只给前面5个元素赋初值,系统自动给后5个元素赋初值为0
-
如果想使一个数组中全部元素值为0,可以写成
int a[10] = {0,0,...,0}; //或者 int a[10] = {0}
-
如果数组不被部分赋初值,那么数组中的数不会被默认赋值为0
二维数组
如何定义
类型说明符 数组名[常量表达式] [常量表达式]
float a[3][4],b[5][10];
引用二维数组
数组名[下标] [下标]
初始化
-
分行给二维数组赋初值
int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
-
可以将所有数据写在一个花括号内,按数组元素在内存中的排列顺序对各元素赋初值。
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
-
可以对部分元素赋初值。
int a[3][4] = {{1},{5},{9}}; //它的作用是对各行第1列(即序号为0的列)的元素赋初值,其余元素值自动为0。
-
如果对全部元素都赋初值(即提供全部初始数据),则定义数组时对第1维的长度可以不指定,但第2维的长度不能省。
int a[3][4] = {1,2,3,4,5,6,7,8,9,10,11,12}; //== int a[][4] = {1,2,3,4,5,6,7,8,9,10,11,12};
字符数组
如果初值个数小于数组长度,则只将这些字符赋给数组中前面那些元素,其余的元素自动定为空字符(即’\0’)
char c[10] = {'c',' ','p','r','o','g','r','a','m'};
如果提供的初值个数与预定的数组长度相同,在定义时可以省略数组长度,系统会自动根据初值个数确定数组长度。
char c[] = {'I',' ','a','m',' ','h','a','p','p','y'};
为了测定字符串的实际长度,C语言规定了一个“字符串结束标志”,以字符串’\0’作为结束标志。如果字符数组中存有若干字符,前面9个字符都不是空字符(‘\0’),而第10个字符是’\0’,则认为数组中有一个字符串,其有效字符为9个。
字符串常用函数
strcat
char strcat (char *dest, const char *src)
把src 所指向的字符串追加到dest所指向的字符串的结尾。
strcpy&strncpy
char strcpy (char *dest, const char *src)
把 src 所指向的字符串复制到 dest。
char strncpy (char *dest, const char *src, size_t n)
把 src 所指向的字符串复制到 dest,最多复制 n 个字符。
strcmp
int strcmp (const char *str1, const char *str2)
把 str1 所指向的字符串和 str2 所指向的字符串进行比较。
如果返回值 < 0,则表示 str1 小于 str2。
如果返回值 > 0,则表示 str2 小于 str1。
如果返回值 = 0,则表示 str1 等于 str2。
strlwr
函数作用是将字符串中大写字母换成小写字母。
strupr
函数作用是将字符串中小写字母换成大写字母。
习题
1. 用筛选法求100之内的素数
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
int main()
{
int prime[101] = {0};
int i;
for(i=2;i<=sqrt(100);i++)
{
if(prime[i]==0)
{
int j = 0;
for(j=i*i;j<=100;j+=i)
prime[j] = 1;
}
}
for(i=2;i<=100;i++)
{
if(prime[i]==0)
printf("%d ",i);
}
printf("\n");
return 0;
}
2.用选择法对10个整数排序
#include<stdio.h>
int main()
{
int min;
int intArr[10] = {-3,6,0,1,2,9,10,1,3,5};
int i,j;
for(i=0;i<10;i++)
{
min = i;
for(j=i;j<10;j++)
{
if(intArr[min]>intArr[j])
{
// int t;
min = j;
}
}
if(min != i)
{
int t;
t = intArr[min];
intArr[min] = intArr[i];
intArr[i] = t;
}
}
printf("------------\n");
for(i=0;i<10;i++)
{
printf("%d ",intArr[i]);
}
printf("\n");
return 0;
}
3. 求一个3 X 3的整形矩阵对角线元素之和
#include<stdio.h>
int main()
{
int arr[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
int sum = 0;
sum = arr[0][0] + arr[1][1] + arr[2][2];
printf("%d\n",sum);
return 0;
}
4. 有一个已经排好序的数组,要求输入一个数后,按原来顺序的规律将它插入数组中
#include<stdio.h>
int main()
{
int insertNum;
scanf("%d",&insertNum);
printf("========插入到数组========\n");
int intArr[10] = {2,6,9,10,13};
int i;
for(i=4;i>=0;i--)
{
if(insertNum>intArr[i])
break;
}
int j = 4;
for(j=4;j>i;j--)
{
intArr[j+1] = intArr[j];
}
intArr[j+1] = insertNum;
printf("===========\n");
for(i=0;i<6;i++){
printf("%d ",intArr[i]);
}
printf("\n");
return 0;
}
5. 将一个数组中的值按逆序重新存放。例如:原来顺序为8 6 5 4 1
。要求改为1,4,5,6,8
#include<stdio.h>
int main()
{
int intArr[] = {-3,6,0,1,2,9,10,1,3,5};
int i;
for(i=0;i<5;i++)
{
int t;
t = intArr[i];
intArr[i] = intArr[10-i-1];
intArr[10-i-1] = t;
}
printf("==========\n");
for(i=0;i<10;i++)
{
printf("%d ",intArr[i]);
}
return 0;
}
6. 输出一下的杨慧三角(要求输出10行)
#include<stdio.h>
int main()
{
int arr[11][11];
arr[1][1] = 1;
arr[2][1] = 1;
arr[2][2] = 1;
int i,j;
for(i=3;i<=10;i++)
{
for(j=1;j<=i;j++)
{
if(j==1||j==i)
arr[i][j] = 1;
else
arr[i][j] = arr[i-1][j-1] + arr[i-1][j];
}
}
printf("============\n");
for(i=1;i<=10;i++)
{
for(j=1;j<=i;j++)
{
printf("%-6d",arr[i][j]);
}
printf("\n");
}
return 0;
}
7. 输出"魔方阵"。所谓魔方阵是指这样的方阵,它的每一行、每一列和对角线之和均相等。例如:
奇数的魔方阵
(1)将1放在第一行中间一列;
(2)从2开始直到n×n止各数依次按下列规则存放;每一个数存放的行比前一个数的行数减1,列数加1(例如上面的三阶魔方阵,5在4的上一行后一列);
(3)如果上一个数的行数为1,则下一个数的行数为n(指最下一行);例如1在第一行,则2应放在最下一行,列数同样加1;
(4)当上一个数的列数为n时,下一个数的列数应为1,行数减去1。例如2在第3行最后一列,则3应放在第二行第一列;
(5)如果按上面规则确定的位置上已有数,或上一个数是第一行第n列时,则把下一个数放在上一个数的下面。例如按上面的规定,4应该放在第1行第2列,但该位置已经被占据,所以4就放在3的下面;
偶数的魔方阵(四阶魔方阵)
#include<stdio.h>
int main()
{
printf("3阶魔方阵输出\n");
int i, j, num, preRow, preCol, nowRow, nowCol;
num = 1;
int cube3 = 3 * 3;
int intArr[3][3] = {0};
while(num <= cube3){
if(1 == num) {
nowRow = 0; nowCol = 1;
preRow = 0; preCol = 1;
intArr[0][1] = num;
}else {
if(preRow == 0 && preCol != 2) { //在第一行
// intArr[2][preCol+1] = num;
// preRow = 2; preCol = preCol + 1;
nowRow = 2; nowCol = preCol + 1;
}else if(preCol == 2 && preRow != 0) { //在最后一列
// intArr[preRow-1][0] = num;
// preRow = preRow - 1; preCol = 0;
nowRow = preRow - 1; nowCol = 0;
}else if(preRow == 0 && preCol == 2) { //第一行,最后一列
// intArr[]
// preRow = 2; preCol = 0;
nowRow = 2; nowCol = 0;
}else {
nowRow = preRow -1;
nowCol = preCol + 1;
}
if(intArr[nowRow][nowCol] != 0) { //上一行,下一列有数
// intArr[preRow+1][preCol] = num;
// preRow = preRow + 1;
// preRow = preRow - 2;
nowRow = preRow + 1;
nowCol = preCol;
}
intArr[nowRow][nowCol] = num;
preRow = nowRow; preCol = nowCol;
}
num++;
}
printf("输入3阶的魔方阵\n");
for(i = 0; i < 3; i++) {
for(j = 0; j < 3; j++) {
printf(" %d ",intArr[i][j]);
}
printf("\n");
}
printf("输出4阶魔方阵\n");
num = 1;
// int cube4 = 4 * 4;
int cube4Arr[4][4] = {0};
for(i = 0; i < 4; i++) {
for(j = 0; j < 4; j++) {
if(!(i == j || i + j == 3)) {
cube4Arr[i][j] = num;
}
num++;
}
}
num = 16;
for(i = 0; i < 4; i++) {
for(j = 0; j < 4; j++) {
if(i == j || i + j == 3) {
cube4Arr[i][j] = num;
}
num--;
}
}
printf("==============\n");
for(i = 0; i < 4; i++) {
for(j = 0; j < 4; j++) {
printf("%4d",cube4Arr[i][j]);
}
printf("\n");
}
return 0;
}
八阶魔方阵
8. 找出一个二维数组中的鞍点,即该位置上的元素在该行上最大,在该列上最小,也可能没有鞍点。
#include<stdio.h>
int main()
{
printf("输入一个5*5的矩阵\n");
int arr[5][5];
int i, j, k, max, pos, min;
for(i = 0; i < 5; i++){
for(j = 0; j < 5; j++){
scanf("%d",&arr[i][j]);
}
}
int flag; //判断是否找到鞍点,1是找到了,0是没找到
for(i = 0; i < 5; i++){
max = arr[i][0];
pos = 0;
for(j = 0; j < 5; j++) {
if(max < arr[i][j]) {
max = arr[i][j];
pos = j;
}
}
flag = 1;
min = arr[i][pos];
for(k = 0; k < 5; k++) {
if(min > arr[k][pos])
flag = 0;
}
if(flag == 1) {
printf("找到鞍点 %d %d %d\n", i + 1, pos + 1, arr[i][pos]); break;
}
}
if(flag == 0) printf("没有找到鞍点\n");
return 0;
}
9. 有15个数按由大到小顺序存放在一个数组中,输入一个数,要求用折半查找法找出该数是数组中第几个元素的值。如果该数不在数组中,则输出"无此数"。
注:如何找出该数是数组中第几个元素?答:通过索引下标(i + 1)即可找到该元素是该数组中第几个元素的值。
#include<stdio.h>
int main()
{
printf("请输入一个有15位数的数组,然后再输入一个数,查找该数在数组中第几位。\n");
int intArr[15];
int i, j, num;
for(i = 0; i < 15; i++) {
scanf("%d", &intArr[i]);
}
printf("数组内容输入完成\n");
scanf("%d",&num);
int low, high, mid;
low = 0; high = 14;
while(low <= high) {
mid = low + high;
if(num == intArr[mid]) {
printf("该数在数组中第%d位,其值为%d\n", mid + 1, num); break;
}else if(num < intArr[mid]) {
high = mid - 1;
}else {
low = mid + 1;
}
}
if(low > high) printf("未在数组中找到%d\n", num);
return 0;
}
10. 有一篇文章,共有3行文字,每行有80个字符。要求分别统计出其中英文大写字母、小写字母、数字、空格以及其他字符的个数。
11. 输出一下图案:
* * * *
* * * *
* * * *
* * * *
* * * *
#include<stdio.h>
int main()
{
for (int i = 0; i < 5; ++i)
{
for (int j = 0; j < i; ++j)
printf(" ");
printf("* * * *\n");
}
return 0;
}
12. 有一行电文,以按下面规律译成密码:
A--->Z a--->z
B--->Y b--->Y
C--->X c--->x
……
即第1个字母编程第26个字母,第i个字母编程第(26-i+1)个字母,非字母字符不变,要求编程序将密码译回原文,并输出密码和原文。
#include<stdio.h>
#include<ctype.h>
#include<string.h>
int main()
{
char str[30];
scanf("%s",str);
int len = (int)strlen(str);
int i;
for(i=0;i<len;i++)
{
if(islower(str[i]))
{
str[i] = 26-(str[i]-'a')-1+'a';
}
if(isupper(str[i]))
{
str[i] = 26-(str[i]-'A')-1+'A';
}
}
printf("%s",str);
return 0;
}
13. 编一程序,将两个字符串连接起来,不要用strcat函数
#include<stdio.h>
int main()
{
void winnieStrcat(char *,char *);
char s1[50], s2[50];
scanf("%s",s1);
scanf("%s",s2);
winnieStrcat(s1,s2);
printf("%s\n",s1);
return 0;
}
void winnieStrcat(char *s1,char *s2) {
char *p1, *p2;
p1 = s1; p2 = s2;
while(*p1 != '\0') {
p1 = p1 + 1;
}
// int i;
for(;*p2 != '\0'; p2++) {
*p1 = *p2;
p1 = p1 + 1;
// p2 = p2 + 1;
}
*p1 = '\0';
}
14.编写一个程序,将连个字符串s1和s2比较,如果s1 > s2,输出一个整数;若s1 = s2,输出0;若s1 < s2,输出一个负数。不要用strcpy函数。两个字符串用gets函数读入。输出的正数或负数的绝对值应是相比较的两个字符串相对应字符的ASCII码的差值。例如,“A"和“C”相比,由于"A” < “C”,应输出负数,同时由于‘A’与‘C’的ASCII码差值为2,因此应输出"-2"。同理:“And”和"Aid"相比较,根据第2个字符比较结果,“n"比"i"大5,因此应输出"5”。
#include<stdio.h>
int main()
{
int winnieStcmp(char *,char *);
char s1[50], s2[50];
gets(s1);
gets(s2);
int r = winnieStcmp(s1,s2);
printf("%d\n",r);
return 0;
}
int winnieStcmp(char *s1,char *s2) {
char *p1, *p2;
p1 = s1; p2 = s2;
while(*p1 != '\0' && *p2 != '\0') {
if(*p1 - *p2 != 0) return (*p1 - *p2);
p1 = p1 + 1;
p2 = p2 + 1;
}
if(*p1 == '\0' && *p2 != '\0') {
return -1*(*p2);
}else if(*p1 != '\0' && *p2 == '\0') {
return *p1;
}else return 0;
// return *p1;
}
15. 编写一个程序,将字符数组s2中的全部字符复制到字符数组s1中,不用strcpy函数。复制时,‘\0’也要赋值过去。’\0’之后的字符不复制。
#include<stdio.h>
int main()
{
void winnieStcpy(char *,char *);
char s1[50], s2[50];
scanf("%s",s1);
scanf("%s",s2);
winnieStcpy(s1,s2);
printf("%s\n",s1);
return 0;
}
void winnieStcpy(char *s1,char *s2) {
char *p1, *p2;
p1 = s1; p2 = s2;
while(*p2 != '\0') {
*p1 = *p2;
p1 = p1 + 1;
p2 = p2 + 1;
}
*p1 = '\0';
}