数组和字符串

数组

  • 相同类型有序数据的集合
组成
  • 数组名:
  • 下标:索引,本质是元素距离首地址(第一元素)的偏移量,以首地址为参照,可使用数组名 + 偏移量访问,下标越大,地址编号越大
  • 元素:数组中每一个匿名的变量空间,每一块空间都有一个独有的地址
  • 特征:在内存里开辟一段连续的相同类型的空间,数组的数据称为元素,同一数组的类型相同

一维数组

数据类型 数组名[ 数组大小 ];
int a[10];

#define NUM 4
int array[NUM];

int num = 5;
int arr[num];

int a[60*30];
  • 数据类型有元素决定,数组名等同于数组变量

  • 数组容量值为整数,可以是常量和符号常量,不能是变量。

  • 定义数组相当与申请一个 连续的 用于容纳指定元素数量 内存单元;相当于定义多个匿名的变量,通过数组名[下标] 访问

  • 申请数组后, 最大下标为数组元素个数,最小为零;未初始化时,数组内为随机值

数组访问
  • 数组需要通过 数组名[ 下标 ] 访问元素,单个访问
int arr[10];   //定义数组
arr[0] = 89;   //数组第一个为89
int a = a[0];  //通过变量访问元素

int c = arr[9];
int b = arr[10];//下标越界
int len = sizeof(arr) / sizeof(a[0]);   //sizeof 返回字节大小

数组访问不能越界

初始化
数据类型 数组名[数组大小] = {常量};
  • 数组可以部分初始化,给前几个元素初始化,未被初始化自动初始化
  • 定义数组时,未定义数组容量,系统会根据初始化元素个数决定数组大小
int arr[10] = {1,5,3,6,4};
int arr[10] = {1,8,8,2,6,7,1};

int a[] = {1,3,6,9,4,5,8};
  • 柔性数组:

  • C99,针对结构体的最后一个成员可以是一个未指定大小的数组

  • 数组容量待定或者待确定的数组 int a[] = {1,2,3,6,5,4};

    冒泡排序

  • 一次指排序一个数,长度为n时,最差需要 n-1 次排好

  • 每次排序需要两数比较,将较大或较小数据向后移动交换,比较完成时,较大的或较小的数出现在结尾。

  • 每轮比较次数 = 元素个数 - 轮数 - 1(因为下标为0)

    • 从后向前:1 2 3 4 5 -> 1 2 3 5 4 -> 1 2 5 3 4 -> 1 5 2 3 4 ->5 1 2 3 4 (第一轮比4次)
#include <stdio.h>

int a[10] = {0};

//向后
void bh(int a[])
{
    int swap = 0;
    for(int i = 0;i < 10-1;i++)
    {
        for(int j = 0; j< 9 -i;j++)
        {
            if(a[j] > a[j+1])
            {
                swap = a[j];
                a[j] = a[j+1];
                a[j+1] = swap;
            }
        }
    }
}

int main(int argc,char *argv[])
{
    int num = 0;
    printf("输入 10 个整数:");
    for(int i = 0 ;i <= 10;i++)
    {
        scanf("%d",&num);
        a[i] = num;
        b[i] = num;
    }
    bh(a);
    printf("the result : ");

    for(int i = 0;i < 10;i++)
    {
        printf("%d ",a[i]);
    }
    printf("\n");

    return 0;
}

//输入一个日期,计算该日是该年的第几天
/*
	1.创建一个数组用于存放一个月的天数,二月为0
	2.闰年判断
	3.使用变量存放天数
	4.前面的月天数 + 该天的日期
*/

#include <stdio.h>

int evy[] = {0,31,0,31,30,31,30,31,31,30,31,30,31};//0月

int check(int y,int m)
{
    if((y % 400 == 0) || (y % 4 == 0 && y % 100 != 0))
        return 1;
    else
        return 0;
}

int main(int argc,char *argv[])
{
    int year= 0, month = 0, day = 0;
    printf("请输入 年 月 日 :");
    scanf("%d %d %d",&year,&month,&day);
    int sum = day;

    if(check(year,month))  
        evy[2] = 29;
    else 
        evy[2] = 28;

    for(int i = 0;i < month;i++)
    {
        sum += evy[i];
    }
    printf("这个月有%2d天 \n",sum); 
    return 0;
}

二维数组

  • 本质是行列式,使用二维数组由 行和列 两部分组成

  • 二维数组可视为 元素是一维数组 的一维数组

  • 列数可视为 元素数组的长度(不可省略)

数据类型 数组名 [行数][列数] ;
int arr[2][3] = {{11,12,13},{21,22,23}};  
int arr2[2][3] = {11,12,13,21,22,23};
int arr3[][3] = {{11,12,13},{21,22,23}};//柔性数组,列数不能省略
int arr4[2][3] = {{11,12},{21}}; 
  • 计算机中,数组的存储顺序是按行执行,即在遍历时按照arr2顺序
  • 未初始化自动填充 0
#include <stdio.h>
//二维数组遍历
int main(int argc,char *argv[])
{
    int arr[][3] = {{11},{21,22},{31,32,33}};
    int r_len = sizeof(arr)/sizeof(arr[0]);
    
    for(int i = 0;i < r_len;i++)   //外层循环遍历行元素
    {
        int c_len = sizeof(arr[i]) / sizeof(int);  
        //获取各行元素个数
        for(int j = 0;j < c_len;j++)
        {
            printf("%-2d ",arr[i][j]);
        }
    }
    return 0;
}

#include <stdio.h>
//转置
int a[][3] = {{11,12,13},{21,22},{31,32}};
int b[3][3];

int main(int argc,char *argv[])
{
    int r_len = sizeof(a) / sizeof(a[0]);

    for(int i = 0;i < r_len;i++)
    {
        int c_len = sizeof(a[i]) / sizeof(a[0][0]);
        for(int j = 0;j < c_len;j++)
        {
            b[j][i] = a[i][j];
        }
    }

    for(int i = 0;i < sizeof(b) / sizeof(b[0]);i++)
    {
       
        for(int j = 0;j < sizeof(b[i]) / sizeof(b[0][0]);j++) 
        {
            printf("%-2d",b[i][j]);
        }
    }
    return 0;
}

字符数组

  • 元素类型为char字符型的数组,用于存储字符串数据

  • 使用char表示一个字节

char a = 'L';
char c = 65;
char ch = "A";  //字符串
  • C语言支持字符串常量,不支持字符串变量;单字节不能使用中文和字符串
char name[size] = "";
char name[][];
  • 未初始化,元素不确定
  • 占不满数组默认使用'\0' 占位,空格使用 '\32' 占位
  • 字符的个数大于长度, 按照语法错误处理
  • 字符个数和数组长度相同,可省略数组长度
char c[8] = {'h','e','l','l','o'};
char c[8] = {'h','e','l','l','o','\0','\0','\0'};

字符串

  • 字符串以 '\0' 结束标志,有 '\0' 就是字符串
char ch[] = {'c','h'};		  //字符数组
char ch[] = {'c','h','\0'};   //字符串
char ch[] = "ch";
char ch[] = "hello\0love";    //输出遇到 '\0' 时表示字符串结束,长度11,即5+1+4+1
// \0  空字符
// 0   数字零 ascii为48
// 空格       ascii为32
  • 用字符串常量,系统自动加上 ’\0’

  • 用sizeof获取字符串大小

  • 用strcpy() 赋值,不能用常量对字符串数据赋值

输入
  • 使用%s输入输出时,输入输出为数组名
  • 对于字符串操作,用到系统提供的函数(API操作)
scanf
scanf("%s",name);     //char数组类型
  • scanf传地址时,仅需要传变量名,数组名代表首地址
  • 使用scanf时,不能出现空格,会自动加入'\0'
fgets
fgets(name,size,FILE*);  
  • 从键盘输入一个字符串常量到字符数组,返回字符数组首地址 ,默认使用12位16进制
  • 使用fgets 可获取输入的字符串,包含\n ,忽略空格
  • 如果输入的字符串不包括 空格和换行 使用scanf fgets
gets
gets(name);
输出
printf
printf("%s",name);
fputs
fputs(name,FILE*(stdout));   
puts
puts(const char *s);   //输出字符串,输出遇到和换行符号会换行
putchar
char ch = putchar(int);

字符串转数值

  • atoi : 字符串转整型
int atoi(char *name);
  • strtol :

    进制:默认十进制 16十六进制 0八进制 2二进制

long strtol(const char *name,char **endptr,进制);//stdlib
printf("%lo",strtol("12",NULL,8));   //10

字符串拼接

#include <string.h>

strcat(name,"内容");  //puts使用,内容为常量和name
  • 内容不要超过name的容量,拼接为后加
  • 连接后没有 \0
#include <stdio.h>
#include <string.h>

int main(int argc,char *argv[])
{
    char name[20];
    printf("input:");
    fgets(name,sizeof(name),stdin);
    strcat(name," hello");
    fputs(name,stdin);
    return 0;
}

字符串拷贝

strcpy(name,"str"); 
  • 字符串赋值不能直接使用赋值字符串
  • 使用strcpy给字符串复制赋值,覆盖复制
#include <stdio.h>
#include <string.h>

int main(int argc,char *argv[])
{
    char name[20];
    printf("input: ");
    fgets(name,sizeof(name),stdin);
    strcpy(name,"lu");
    fputs(name,stdout);
    return 0;
}

字符串比较

int num = strcmp(name,str);
  • 不能用== 比较
  • 比较两串对应位置比较,从左向右字典序比较,遇到\0 结束
  • 若相等 返回值为1 ;name>str 返回正数;返回正数是比较的name相应位置的ascii大于str
  • name和str可以是数组或常量
#include <stdio.h>
#include <string.h>

int main(int argc,char *argv[])
{
    char name[20];
    printf("input: ");
    scanf("%s",name);
    int num = strcmp(name,"lu");
    if(!num)
    {
       fputs("\nsame\n",stdout);
    }
    return 0;
}

字符串长度

unsigned long int num = strlen(name);
  • 返回包含的字符个数,不含\0

  • 在字符串中间有\0 当作两个字符

#include <stdio.h>
#include <string.h>
int main(int argc,char *argv[])
{
    char name[20];
    fputs("input:",stdout);
    scanf("%s",name);
    
    unsigned int num = strlen(name);
    
    printf("the len:%d",num);
    
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值