C语言笔记 16 —— 数组基础

数组运算


最基础的搜索程序:在给定的数据中,如何找出某个数据是否存在?

cpp 复制代码
#include <stdio.h>

/**
找出key在数组a中的位置
@param key 要寻找的数字
@param a 要寻找的数组
@param length 数组a的长度
@return 如果找到,返回其在a中的位置;如果找不到则返回-1
*/
int search( int key, int a[], int length );

int main(void)
 {
    int a[] = {2,4,6,7,1,3,5,9,11,13,23,14,32};
    int x;
    int loc;
    printf("请输入一个数字:");
    scanf("%d", &x);
    loc=search(x, a, sizeof(a)/sizeof(a[0]));
    if ( loc !=-1){
        printf("%d在第%d个位置上\n", x, loc);
    } else {
        printf("%d不存在\n", x);
    }

    return 0;
}

int search(int key, int a[], int length)
{
    int ret = -1;
    int i;
    for ( i=0; i< length; i++) {
        if(a[i] == key ) {
            ret = i;
            break;
        }
    }
    return ret;
}

数组的集成初始化

int a[] = {2,4,6,7,1,3,5,9,11,13,23,14,32};

直接用大括号给出数组的所有元素的初始值

不需要给出数组的大小,编译器会自动数
可以加一段测试代码
运行结果

集成初始化时的定位

int a[10] = {

[0] = 2, [2] = 3, 6,

};

>> a0=2, a2=3, a3=6, 其余都为0

用[n]在初始化数据中给出定位

没有定位的数据接在前面的位置后面

其他位置的值补零

也可以不给出数组大小,让编译器算

特别适合初始数据稀疏的数组

数组的大小

回忆:sizeof能给出整个数组所占据的内容的大小,单位是字节

sizeof(a[0])给出数组中单个元素的大小,于是相除就得到了数组的单元个数,这样的代码,一旦修改数组中初始的数据,不需要修改遍历的代码

数组的赋值

int a[] = {2,4,6,7,1,3,5,9,11,13,23,14,32};

int b[] = a;

错误❌

数组变量本身不能被赋值,要把一个数组的所有元素交给另一个数组,必须采用遍历

正确写法✔:(唯一方法)

for ( i=0; i<length; i++ ) {

b[i] = a[i];

}

遍历数组

  • 通常都是使用for循环,让循环变量i从0到<数组的长度,这样循环体内最大的i正好是数组最大的有效下标

常见错误:

①循环结束条件是<=数组长度

②离开循环后,继续用i的值来做数组元素的下标

  • 数组作为函数参数时,往往必须再用另一个参数来传入数组的大小。因为不能在[]中给出数组的大小,也不能再利用sizeof来计算数组的元素个数

数组例子


回顾:判断素数

int isPrime(int x);

int main(void)

{

int x;

scanf("%d", &x);

if ( isPrime(x) ) {

printf("%d是素数\n", x);

} else {

printf("%d不是素数\n", x);

}

return 0;

}

最开始的代码:

从2到i-1测试是否可以整除:当n很大时,就会重复很多遍


去掉偶数后从3到i-1,每次加2

int isPrime(int i)

{

int ret = 1;

int k;

if ( i==1 ||

(i%2 == 0 && i!=2 ) )

ret = 0;

for ( k=3; k<i; k+=2) {

if (i%k == 0 ) {

ret = 0;

break;

}

}

return ret;

}

会循环n/2遍


无需到x-1,到sqrt(x)就够了

int isPrime(int i)

{

int ret = 1;

int k;

if ( i==1 ||

(i%2 == 0 && i!=2 ) )

ret = 0;

for ( k=3; k<sqrt(i); k+=2) {

if (i%k == 0 ) {

ret = 0;

break;

}

}

return ret;

}

只需要循环sqrt(x)遍


判断是否能被已知的且<x的素数整除

cpp 复制代码
#include <stdio.h>

int main(void)
{
    const int number=100;
    int prime [number]={2};
    int count=1;
    int i=3; 
    while (count< number ){ 
        if(isPrime(i, prime, count)){ 
            prime [count++]=i;
        }
        i++;
    }
    for (i=0; i<number; i++){ 
        printf("%d", prime [i]);
        if((i+1)%5) printf("\t");
        else printf("\n");
    } 
    return 0;
}

int isPrime(int x, int knownPrimes[], int numberOfKnownPrimes) 
{
    int ret = 1;
    int i; 
    for (i=0;i<numberOfKnownPrimes; i++){ 
        if(x % knownPrimes[i]==O){ 
            ret =0;
            break;
        }
    }
    return ret;
}

构造素数表(n以内)

①令x为2

②将2x、3x直到ax<n的数标记为非素数

③令x为下一个没有标记为非素数的数,重复②,直到所有数都尝试完毕

1.开辟prime[n],初始化其所有元素为1,prime[x]为1,表示x是素数
2.令x=2
3.如果x是素数,则对于(i=2;x*i<n;i++)令prime[i*x]=0
4.令x++,如果x<n,重复3,否则结束

二维数组


二维数组

eg. int a[3][5];

通常理解为a是一个3行5列的矩阵:

|-------------|-------------|-------------|-------------|-------------|
| a[0][0] | a[0][1] | a[0][2] | a[0][3] | a[0][4] |
| a[1][0] | a[1][1] | a[1][2] | a[1][3] | a[1][4] |
| a[2][0] | a[2][1] | a[2][2] | a[2][3] | a[2][4] |

二维数组的遍历

for ( iii<3; i++ ) {

for ( j=0; j<5; j++ ) {

a[i][j] = i*j;

}

}

a[i][j]是一个int,表示第i行第j列上的单元

(外层遍历行,内层遍历列)

a[i,j]表示:a[j]

二维数组的初始化

列数是必须给出的,行数是可以由编译器自动来数

每行一个{},逗号分隔

最后的逗号可以存在,如果省略,表示补零

tic-tac-toe游戏

读入一个3×3的矩阵,矩阵中的数字为1表示该位置上有一个X,为0表示为O

程序判断这个矩阵中是否有获胜的一方,输出表示获胜一方的字符X或O,或输出无人获胜

读入矩阵

count int size=3;

int board[size][size];

int i,j;

int num0fX;

int num0fO;

int result = -1; // -1:没人赢,1:X赢,0:O赢

// 读入矩阵

for ( i=0; i<size, i++ ) {

for ( j=0; j<size; j++ ) {

scanf("%d", &board[i][j] );

}

}

检查行

// 检查行

for (i=0; i<size && result ==1;i++) {

num0fO= num0fX=0;

for(j=0; j<size; j++) {

if ( board[i][j]==1) {

num0fX ++;

}else {

num0fO ++;

}

}

if (num0fO = size ){

result=0;

} else if (num0fX== size ){

result=1;

}

}

检查列

if ( result==1){

for (j=0; j<size && result==-1; j++){

num0O = num0fX=0;

for (i=0;i<size; i++){

if ( board[i][j]==1) {

num0fX ++;

} else {

num0fO ++;

}

}

if(num0fO== size ){

result=0;

} else if (numofX- size ){

result=1;

}

}

}

检查对角线

num0fO= num0fX=0;

for(i=0; i<size; i++){

if( board[il[i]==1) {

num0fX ++;

} else {

num0fO ++;

}

}

if( num0fO==size ){

result=0;

}else if (numofX== size ){

result=1;

num0fO= num0fx=0;

for(i=0;i<size; i++){

if( board[i][size-i-1]==1){

num0fX ++;

} else {

num0fO ++;

}

}

相关推荐
计算机小白一个4 分钟前
蓝桥杯 Java B 组之设计 LRU 缓存
java·算法·蓝桥杯
万事可爱^38 分钟前
HDBSCAN:密度自适应的层次聚类算法解析与实践
算法·机器学习·数据挖掘·聚类·hdbscan
李白同学1 小时前
【C语言】结构体内存对齐问题
c语言·开发语言
敲敲敲-敲代码2 小时前
【SQL实验】触发器
数据库·笔记·sql
楼台的春风2 小时前
【MCU驱动开发概述】
c语言·驱动开发·单片机·嵌入式硬件·mcu·自动驾驶·嵌入式
Moonnnn.2 小时前
51单片机学习——动态数码管显示
笔记·嵌入式硬件·学习·51单片机
黑子哥呢?2 小时前
安装Bash completion解决tab不能补全问题
开发语言·bash
青龙小码农2 小时前
yum报错:bash: /usr/bin/yum: /usr/bin/python: 坏的解释器:没有那个文件或目录
开发语言·python·bash·liunx
大数据追光猿3 小时前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
Dream it possible!3 小时前
LeetCode 热题 100_在排序数组中查找元素的第一个和最后一个位置(65_34_中等_C++)(二分查找)(一次二分查找+挨个搜索;两次二分查找)
c++·算法·leetcode