C语言基础(数组篇)

数组基本概念

概念:具有一定顺序的若干变量的集合

定义格式:

存储类型 数据类型 数组名[元素个数]

例:int arr[5];

数组名:代表数组的首地址(地址常量),不能为左值,不能被重新赋值

访问元素:数组名[下标],下标的范围:0 ~ n-1

n:元素个数

arr[0]:访问第一个元素

arr[3]:访问第四个元素

修改数组里面的元素:数组名[下标]=新值

注意不要越界,数组越界可能不会报错,需要自己注意

特点:

  • 数据类型相同,元素的数据类型要和数组的数据类型一致
  • 内存连续
  • 数组名[下标]--->变量名 数组内的元素--->变量的值

注意:

  • 下标的范围:0 ~ n-1
  • 数组名命名需要符合标识符的命名规则
  • 在同一个函数中,数组名不能与其他变量名相同

一维数组

定义格式

存储类型 数据类型 数组名[元素个数]

例:int arr[5];

数组名:代表数组的首地址(地址常量),不能为左值,不能被重新赋值

访问元素:数组名[下标],下标的范围:0 ~ n-1

n:元素个数

arr[0]:访问第一个元素

arr[3]:访问第四个元素

修改数组里面的元素:数组名[下标]=新值

注意不要越界,数组越界可能不会报错,需要自己注意

初始化

全部初始化:

int arr[3]={1,2,3}; //1 2 3

部分初始化:未初始化部分值为0

int arr[3]={1,2} //1 2 0

未初始化:未初始化的部分为随机值,需要单独赋值,不能整体赋值

int arr[3]; //随机值

引用

  • 先定义后引用
  • 每次只能访问一个是数组元素,想引用数组中的所有元素需要循环遍历
  • 引用时防止数组的越界,虽然编译器有时不会报错
  • 对数组中每一个元素的地址的打印用%p格式

内存连续

元素 大小 地址

数组大小

sizeof(数组名);

大小=数据类型的大小 * 元素个数;

int a[6]; // 4*6 = 24

float buf[3] = {1.2, 3,1}; // 4*3 = 12

double c[2]; // 8*2 = 16

计算数组中元素个数:sizeof(数组名)/sizeof(数组的数据类型)

遍历数组

将循环变量作为下标,循环遍历数组

清零函数

bzero

#include <strings.h>

void bzero(void *s,size_t n);

功能:将数组的内存空间设置为 0

参数:s:要清空的数组的首地址

n:数组的大小(字节)

返回值:无

用法:bzero(数组名,sizeof(数组名));

memset

#include <strings.h>

void *memset(void *s,int c,size_t n);

功能:将数组的内存空间设置为 0

参数:s:要清空的数组的首地址

c:你要设置的值

n:数组的大小(字节)

返回值:清空的数组的首地址

用法:memset(数组名,设置的值,sizeof(数组名));

字符数组

概念:字符数组的里面存放的都是字符 实际存放的是字符串

定义格式

char str[3]={'a','b','c'}; //逐个字符赋值

char str[]={'a','b','c'}; //逐个字符赋值

char str[]="hello"; //使用字符串赋值 sizeof(str)=6(系统添加\0)

注意:字符串赋初值时经常省略数组的长度(\0),以后面实际赋值为准,要注意数组越界问题

输入输出

输入

1) 直接使用%s输入

char buf[32];

scanf("%s", buf); // 从终端输入字符串到数组 buf,但是遇到空格或者\n 会结束

sacnf("%[^\n]", buf); // 从终端输入字符串到数组 buf,直到遇到\n 结束

2) gets

char *gets(char *s);

功能:从终端输入字符串

参数:目标字符串的首地址

返回值:目标字符串的首地址

注意:谨慎使用、使用时会报警告,不检查数组越界

输出

1) printf("%s\n", buf); // 遇到 \0 就会结束

2) puts

int puts(const char *s) ;

功能:向终端输出字符串

参数:要输出字符串的首地址

返回值:输出字符的个数

计算字符串的实际长度

1) 循环遍历,找到\0位置
2) strlen

#include<string.h>

功能:计算字符串的实际长度(不包括\0)

参数:要计算的字符串的首地址

返回值:字符串的实际个数

3)sizeof和strlen的区别:

  • sizeof 是关键字;strlen 是函数
  • sizeof 计算数据所占空间字节大小;stelen 计算字符串的实际个数
  • 在元素个数省略的情况下,sizeof 包括\0,strlen 不包括 \0
  • 在这情况下计算字符串长度 sizeof 比 strlen 大 1

排序

冒泡排序

排序思想:相邻的两个数进行比较(两两比较),如果前者大与后者则交换位置(每一轮排序完成确定一个元素的位置)

例:int arr[]={5,4,3,2,1};

// 冒泡排序
#include <stdio.h>
int main(int argc, char const *argv[])
{
    int arr[] = {5, 4, 3, 2, 1};
    int i, j, temp;
    for (j = 0; j < sizeof(arr) / sizeof(int) - 1; j++) // 比较的轮数
    {
        for (i = 0; i < sizeof(arr) / sizeof(int) - 1 - j; i++) // 每一轮比较的次数
        {
            if (arr[i] > arr[i + 1])
            {
                temp = arr[i];
                arr[i] = arr[i + 1];
                arr[i + 1] = temp;
            }
        }
    }
    for (i = 0; i < 5; i++)
    {
        printf("%d", arr[i]);
    }
    printf("\n");
    return 0;
}

分析:

第一轮:j=0

5 4进行比较:4 5 3 2 1

5 3进行比较:4 3 5 2 1

5 2进行比较:4 3 2 5 1

5 1进行比较:4 3 2 1 5

第二轮:j=1
4 3进行比较:3 4 2 1 5
4 2进行比较:3 2 4 1 5
4 1进行比较:3 2 1 4 5

第三轮:j=2
3 2进行比较:2 3 1 4 5
3 1进行比较:2 1 3 4 5

第四轮:j=3
2 1进行比较:1 2 3 4 5

选择排序

排序思想:在n个数中找最小值的下标暂时存储,然后和正确的位置交换(每一轮排序完成确定一个元素的位置)

例:int arr[] = {5, 3, 2, 4, 1};

// 选择排序
#include <stdio.h>
int main(int argc, char const *argv[])
{
    int arr[] = {5, 3, 2, 4, 1};
    int i = 0, j, temp;
    while (i < sizeof(arr) / sizeof(int) - 1) // 排序的轮数
    {
        int min = i;                                        // 待排序数组中最小值下标
        for (j = i + 1; j < sizeof(arr) / sizeof(int); j++) // 每一轮比较的次数
        {
            if (arr[j] < arr[min]) // 判断当前值与最小值的大小关系
            {
                min = j; // 更新最小值下标
            }
        }
        // 通过交换确定最小值位置
        if(min!=i)
        temp = arr[i];
        arr[i] = arr[min];
        arr[min] = temp;
        i++;
    }
    // 输出数组内容
    for (i = 0; i < sizeof(arr) / sizeof(int); i++)
    {
        printf("%d", arr[i]);
    }
    printf("\n");
    return 0;
}

分析:

找到最小值下标,与 arr[i]交换

第一次

begin 0

5 3 2 4 1 min 0

5 3 2 4 1 min 1

5 3 2 4 1 min 2

5 3 2 4 1 min 2

5 3 2 4 1 min 4

arr[4]与 arr[0]交换

1 3 2 4 5

第二次

begin 1

1 3 2 4 5 min 1

1 3 2 4 5 min 2

1 3 2 4 5 min 2

1 3 2 4 5 min 2

arr[2]与 arr[1]交换

1 2 3 4 5

二维数组

定义格式

存储类型 数据类型 数组名[行数][列数];

例:int arr[2][3];

访问元素

数组名[行下标][列下标] (下标范围:0 ~ 行数-1,0 ~ 列数-1)

arr[0][0]:第一行第一列的元素

arr[1][2]:第二行第三列的元素

注意:行数可以省略,但是列数不能省略

int arr[][3];

二维数组元素个数 = 行数 * 列数

数组名

a:表示第一行的首地址

a+1:表示第二行的首地址

a[0]:表示第一行第一列的首地址

a[1]:表示第二行第一列的首地址

初始化

1) 全部初始化:

int arr[2][3] = {1, 2, 3, 4, 5, 6}; // 1 2 3 4 5 6 顺序赋值

int arr[2][3] = { {1, 2, 3}, {4, 5, 6} }; // 1 2 3 4 5 6 按行赋值

2) 部分初始化:

int arr[2][3] = {1, 2, 3, 4}; // 1 2 3 4 0 0 顺序赋值

int arr[2][3] = {{1, 2}, {4, 5}}; // 1 2 0 4 5 0 按行赋值

3) 未初始化:

int arr[2][3]; // 随机数,需要单独赋值

数组大小

大小= 数据类型大小 * 行数 * 列数;

sizeof(数组名);

遍历数组

双层for:外层循环控制行,内层循环控制列

#include <stdio.h>
int main(int argc, char const *argv[])
{
    int i, j, sum = 0;
    int arr[3][3];
    printf("input:\n");
    for (i = 0; i < 3; i++)//控制行数
    {
        {
            for (j = 0; j < 3; j++)//控制列数

                scanf("%d", &arr[i][j]);
        }
    }
    for (i = 0; i < 3; i++)//控制行数
    {
        for (j = 0; j < 3; j++)//控制列数
        {
            printf("%d ", arr[i][j]);//输出每一个元素
            sum += arr[i][j];
        }
        printf("\n");//换行
    }
    printf("sum=%d\n", sum);
    printf("%p", arr);//arr打印数组首地址	 
    printf("%p", arr[0]);//arr[0]打印第一行第一列元素的地址
    return 0;
}

数组编程练习

示例1:数组求和

#include <stdio.h>
int main(int argc, char const *argv[])
{
    int arr[3];
    int i;
    int sum=0;
    for (i = 0; i < sizeof(arr)/sizeof(int); i++)

    {
        scanf("%d", &arr[i]);
    }
    for (i = 0; i < sizeof(arr)/sizeof(int); i++)

    {
        sum+=arr[i];
        printf("%d", arr[i]);
        printf("  %ld", sizeof(arr[i]));
        printf("  %p\n",&arr[i]);
    }
    printf("sum=%d\n",sum);
    printf("%ld\n",sizeof(arr));
    return 0;
}


示例2:计算斐波那契数列的前15项并逆序输出(1 1 2 3 5 8 13 21)

#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
    int arr[15];
    int i, j;
    arr[0] = 1;
    arr[1] = 1;
    int n = sizeof(arr) / sizeof(int);
    for (i = 2; i < n; i++)
    {
        arr[i] = arr[i - 1] + arr[i - 2];
        // printf("%d\n", arr[i]);
    }

    // bzore(arr,sizeof(arr));
    // memset(arr,0,sizeof(arr));
    for (i = 14; i >= 0; i--)
    {
        printf("%d ", arr[i]);
    }
    return 0;
}


示例3:3行4列的矩阵,输出其最大值及所在行和列

#include <stdio.h>
int main(int argc, char const *argv[])
{
    int i, j, max, h, l;
    int arr[3][4];
    printf("input:\n");
    for (i = 0; i < 3; i++)
    {
        {
            for (j = 0; j < 4; j++)
                scanf("%d", &arr[i][j]);
        }
    }
    max = arr[0][0];
    for (i = 0; i < 3; i++)
    {
        for (j = 0; j < 4; j++)
        {
            if (arr[i][j] > max)
            {
                max = arr[i][j];
                h = i + 1;
                l = j + 1;
            }
        }
    }
    printf("%d\n", max);
    printf("%d %d\n", h, l);
    return 0;
}


示例4:在终端输入大写字母,小写字母,数字,空格,分别输出他们的个数

#include <stdio.h>
int main(int argc, char const *argv[])
{
    int n = 0, m = 0, k = 0, b = 0;
    char buf[32] = {};    // 初始化
    // scanf("%s", buf);     // 遇到空格或\n结束
    scanf("%[^\n]", buf); // 遇到\n结束
    for (int i = 0; i < 32; i++)
    {
        if (buf[i] == ' ')
        {
            k++;
        }
        else if (buf[i] >= 'a' && buf[i] <= 'z')
        {
            n++;
        }
        else if (buf[i] >= 'A' && buf[i] <= 'Z')
        {
            m++;
        }
        else if (buf[i] >= '0' && buf[i] <= '9')
        {
            b++;
        }
    }
    printf("%s\n", buf);
    printf("空格:%d 小写字母:%d 大写字母:%d 数字:%d", k, n, m, b);
    return 0;
}


示例5:实现字符串大小写转换

#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
    char buf[32] = {};
    printf("input str:\n");
    scanf("%[^\n]", buf);
    int i;
    int n = strlen(buf);
    for (i = 0; i < n; i++)
    {
        if (buf[i] >= 65 && buf[i] <= 90)
        {
            buf[i] += 32;
        }
        else if (buf[i] >= 97 && buf[i] <= 122)
        {
            buf[i] -= 32;
        }
    }
    printf("%s\n", buf);
    return 0;
}


示例6:将字符串中所有下标为奇数位置上的字母转换为大写,若该位置上不是字母,则不转换

#include<stdio.h>
#include<string.h>
int main(int argc, char const *argv[])
{
    char s[32];
    printf("input:\n");
    scanf("%s",s);
    int i;
    for(i=0;i<strlen(s);i++)
    {
        if(i%2!=0&&s[i]>=97&&s[i]<=122)
        {
            s[i]=s[i]-32;
        }
    }
    printf("%s\n",s);
    return 0;
}

 示例7:将hello字符串倒置

#include <stdio.h>
#include <string.h>
int main(int argc, char const *argv[])
{
    char buf[32] = "hello";
    char ch;
    int i, n = strlen(buf);
    for (i = 0; i < n/2; i++)
    {
        ch = buf[i];
        buf[i] = buf[n - i - 1];
        buf[n - i - 1] = ch;
    }
    printf("%s\n", buf);
    return 0;
}

示例8:

求s=a+aa+aaa+aaaa+…,其中a是一个数字,n表示a的位数,a和n由键盘输入

输出内容:s=2+22+222+2222+22222=24690

#include <stdio.h>
#include <string.h>
int main()
{
    int s = 0, a, n;
    int buf[32] = {};
    printf("输入数字:\n");
    scanf("%d", &a);
    printf("输入几个数相加:\n");
    scanf("%d", &n);
    buf[0] = a;
    printf("s=%d",a);
    for (int i = 1; i < n; i++)
    {
        buf[i] = 10 * buf[i - 1] + a;
        printf("+%d", buf[i]);
        s += buf[i];
    }
    s += a;
    printf("=%d\n", s);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值