字符串,字符数组

数组

处理数量较大的需求
数组可以存放多个同一类型的数据,是一种构造类型,传递方式引用传递(传递地址)

构造类型:数组,结构体,共用体,枚举
快速入门:计算数组大小sizeof()

#include <stdio.h>
void main(){
    //定义数组
    double array1[6];
    array1[0] = 3;//第一个元素
    array1[2] = 2;
    array1[3] = 4;
    array1[4] = 5;
    array1[5] = 6;
    double sum = 0.0;
    double ave = 0.0;
//数组遍历
    int i,arrlen;
     //得到数组所含元素个数,sizeof(array1)为数组总大小,sizeof(double)为一个double所占的空间
    arrlen = sizeof(array1)/sizeof(double);
    for(i=0;i<=arrlen;i++){
        sum += array1[i];//累计求和
        }
    ave = sum/6;
    printf("和为%.2f, 平均值为%.2f, 数组大小", sum, ave);
}

数组内存

int a[5]:a这个数组最多存放5个int类型的数据
数组内存:
a这个数组名称指向数组的首地址,a[0]代表第一个元素(举例:一栋楼:a代表楼层号,a[0]代表第几个房间,房间中放的是元素)。
数组中的元素是连续分布的a[0]地址是0x1112,那么a[1]的地址为0x1112 + int字节数

访问数组元素

通过下标访问

#include <stdio.h>
int main(){
    //从终端输入五个成绩,并保存和输出
    double arr[5];
    int arraylen = sizeof(arr)/sizeof(double);
    int i,j;
    for(i=0;i<arraylen;i++){
        printf("请输入一个小数:");
        scanf("%lf", &arr[i]);//随着循环,一个一个从终端输入
    }
    printf("\n============\n");
    for(j=0; j<arraylen; j++){
        printf("arr[%d]=%.2f ", j, arr[j]);//随着循环,一个一个输出
    }
     //其他初始化方式
    int arr1[3] = {10,20,30};
    int arr2[] = {10,22};//在定义时直接省略数组大小,会自动判断
    return 0;
}

注意事项

数组一旦定义,大小固定,不能动态变化
数组在创建后,如果没有赋值,则全局数组默认为0,非全局数组会造成初始值为机器垃圾值,导致程序崩溃
数组下标只能在指定范围内运用
当把数组传递给函数或者变量时,函数变量操作数组会影响到原数组

#include <stdio.h>
void f1(int arr[]){
    int i;
    int len = sizeof(arr)/sizeof(int);
    for(i=0;i<len;i++){
    arr[i]=arr[i+1]+1;
    }
}
int main(){
    int i;
 int arr1[3] = {10,20,30};
    for(i=0;i<3;i++){
        printf("arr1[%d]=%d ",i,arr1[i]);
    }
    f1(arr1);
    for(i=0;i<3;i++){
        printf("arr1[%d]=%d ",i,arr1[i]);
    }
    return 0;
}

练习

1、打印26个英文字母

#include <stdio.h>
void main(){
    //创建数组,放置英文A到Z,并打印
    char arr[26];
    int i;
    for(i=0;i<26;i++){
        arr[i]='A'+i;
    }
    for(i=0;i<26;i++){
        printf("arr[%d]=%c ",i,arr[i]);
    }
}

2、求数组最大值,并返回下标

#include <stdio.h>
//求数组最大值,并得到对应下标
void main(){
    int arr[6] = {-1, 3, 2, 12, 1, 66};
    int a = 0, i = 0, maxIndex = 0;
    int arrle1 = sizeof(arr)/sizeof(int);//注意,计算结果是4,而不是5
    for(i=0;i<arrle1;i++){
        maxIndex = arr[i]>a ? i: maxIndex ;//每替换一次,就改变maxIndex的值
        //maxIndex的判断需放在上面,因为第二条语句已经是赋值语句。再判断就没有意义
        a = arr[i]>a ? arr[i] : a;//如果arr[i]中的值大于a,则赋值给a
        
    }
    printf("%d %d",a, maxIndex);

}

字符数组与字符串

定义

用来存放字符的数组
变量中存放的是首地址
char a[10]
char a1[5][20] 二维数组
char c[10]={‘x’, ‘c’} 为部分字符数组赋值
char 1[ ]={“hellotom"}不需要自己加\0
char a4[]={‘h’,‘e’,‘l’,‘l’,‘o’,‘T’, ‘T’,‘o’,‘m’};以这种方式定义的字符串需要自己加\0,正确形式应该为:
char a4[ ]={‘h’,‘e’,‘l’,‘l’,‘o’,‘T’, ‘T’,‘o’,‘m’,‘\0’};
用字符数组存放字符串
在c语言中,字符串实际上是使用null字符 (‘\0’) 终止的一维字符数组,因此一个以null结尾的字符串,包含了组成字符串的字符,
比如char c[10]={‘x’, ‘c’} 的存放为:先开辟10个连续的空间x, c, \0 ,会从第一个字符开始输出,遇到\0就停止,十进制的0对应的ASCII就是0
char str[3] = {‘a’,‘b’,‘c’};
printf(“\n%s”,str);
输出会乱码,因为没有地方存放\0,会出现乱码
可以自己加char str[4] = {‘a’,‘b’,‘c’,‘\0’};
或者可以定义为:char s[ ]=“hello”,既不浪费空间又会默认加\0
字符指针指向字符串:

  • 指针自己有一个地址,首先会在内存中会有一个指针变量:pstr,也会开辟hello的存储空间,由于是指针,并不直接指向数组字符串,它指向一个空间(指针会指向一个空间),此指针本身有地址:0X122,此空间中存放的是h的地址0X166,
    具体如下示意图:
    一个字符占用一个字节:e的地址:0X1167
    在这里插入图片描述
    注意%s对应的才是char* , %c对应的是char
    char* st1="hello";
    printf("%s",st1);
字符数组和字符指针的区别

字符数组有若干个元素组成,每个元素放一个字符,字符数组直接指向首地址;字符指针变量中存放的是地址,不是将字符串放到字符指针变量中;
字符数组赋值:
char str[12];//str是数组名,数组名的值是数组首元素的指针常量。实际上是一个常量,常量是无法改值的。
str=“hello”;//错误,因为会开辟另外一块空间存放hello,而str实际上一个常量(是否常量有待讨论,实际上应该不是常量,),无法改值,也无法作为左操作符被赋值
str[1]=“h”;可以
字符指针赋值
char* a=“yes”;
a=“hello”;//可以,改变a的指向,a本身的地址不改变,原来的yes会被回收

#include <stdio.h>
#include <string.h>
void main(){
    // char ss1[]="helo";
    // int i=0;
    // int len = strlen(ss1);
    // for(i = 0; i<len;i++){
    //     printf("%c ",ss1[i]);
    // } 
    char* st1="hello";
    printf("st1本身地址:%p\nst1指向的地址:%p\n",&st1,st1);
    st1 = "hel";
    printf("st1本身地址:%p\nst1指向的地址:%p ",&st1,st1);
}

运行结果:
在这里插入图片描述
总结:定义了一个字符数组,那么它有确定的内存地址,而定义一个字符指针变量时,它并未指向某个确定的字符数据,并且可以多次赋值

访问和遍历

#include <stdio.h>
#include <string.h>
void main(){
    char ss1[]="helo";
    int i=0;
    int len = strlen(ss1);
    for(i = 0; i<len;i++){
        printf("%c ",ss1[i]);
    } 
}

字符串常用函数

strcpy(s1,s2):复制s2到s1
strcat(s1,s2):连接s2到s1
strlen(s1):计算长度
strcmp(s1,s2):比较s2和s1,若相等,则返回0;若s1>s2,返回大于0;s1<s2,返回小于0:即前面的大就返回大于0的(默认对应的字符值的ASCII进行比较)
strchr(s1,ch):返回s1中ch第一次出现的位置
strstr(s1,s2):返回一个指针,指向字符串s1中字符串s2第一次出现的位置

#include <stdio.h>
#include <string.h>
void main(){
    char a1[]={"hello Tom"};
    char a2[]={"hello"};
    //char ch='h';
    int *po=strchr(a1,'h');
    printf("Tom第一次出现的的位置:%p\n",strstr(a1,a2));
    printf("T第一次出现的的位置:%p ",strchr(a1,'h'));
   
       char a1[]={"hello Tom"};
}
  • 19
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值