C语言基础之数组、字符串、指针


一、数组

1、数组

(1)、数组属于构造数据类型

(2)、数组的特点
   只能存放一种类型的数据,比如int类型的数组、float类型的数组。数据称为“元素”,元素有顺序之分,每个元素都有一个唯一的下标(索引),从0开始

//数组的初始化和遍历
#include <stdio.h>
int main()
{
    //正确的初始化方式
    /*
     int age[5]={10,9};代表给前两个角标处赋值
     int age[50]={[2]=34,[3]=56};代表给2和3位置赋值
     int age[]={1,2,3};代表该数组长度为3
     int age['s']={1,2};
     
     也可以先声明再初始化:
     int age[3];
     age[0]=2;
     age[1]=3;
     age[2]=45;
     */
    
    printf("----------------------------------------\n");
    
    //错误的初始化方式
    /*
     int age[]; 这是错误的,不明确数组长度
     
     int age[3];
     age={1,2,3};这是错误的,大括号只能在声明时这样定义。而且,数组名代表的是一个内存地址
     */
    
    printf("----------------------------------------\n");

    /*
     数组长度为变量时
     int i=5;
     int age[i]={1,2,3};//这是错误的,要想在定义数组的同时进行初始化,
     数组元素个数必须是常量或者常量表达式
     
     int age[i];
     age[0]=2;
     age[2]=4;//这样初始化就是正确的
     
     */
    
    
    printf("----------------------------------------\n");
    
    //遍历数组
    int ages[]={23,12,34,43,22,11};
    //C语言数组木有像java中length属性,所以计算数组长度可以用数组总字节数除以
    //每个元素所占字节数,也就是sizeof(ages)/sizeof(int)
    for(int i=0;i<sizeof(ages)/sizeof(int);i++)
    {
            printf("%d\t",ages[i]);
    }
    printf("\n");
    return 0;
}
(3)、数组的内存存储细节

     数组名就代表数组地址,所以&array和array是一样的。寻址过程中,数组和数组之间是先从高位分配,但是个元素之间则是从地位分配.

#include <stdio.h>
int main()
{
    //定义两个数组
    int ages[3]={1,2,3};
    char c[2]={78,56};
    
    //打印数组字节数
    printf("ages的长度是%ld个字节\nages的长度是%ld个字节\n\n",sizeof ages,sizeof c);
    
    //打印两个数组地址
    printf("ages的地址是%p\nc的地址是%p\n",ages,c);
    
    //打印两个数组中个元素的地址
    for(int i;i<3;i++)
    {
        printf("ages[%d]的地址是:%p\n",i,&ages[i]);
    }
    
    printf("\n\n");
    
    for(int i;i<2;i++)
    {
        printf("c[%d]的地址是:%p\n",i,&c[i]);
    }
    
    return 0;

}

//输入3个人的成绩并计算平均值
#include <stdio.h>
int main()
{
    //定义1个长度为3的数组
    int ages[3];
    
    int sum=0;
    
    //循环输入3个成绩
    for(int i;i<3;i++)
    {
        printf("请输入第%d个同学的成绩,按回车键结束\n",i+1);
        scanf("%d",&ages[i]);
        sum+=ages[i];
    }
    
    //输出平均值
    printf("平均值是%0.3f",sum/3.0);
    return 0;

}

(4)、数组与函数

    基本数据类型作为形参是值传递,数组则是地址传递。数组传递时,会被当成指针类型,指针在64位编译器下长度均为8个字节

//输入3个人的成绩并计算平均值
#include <stdio.h>
int maxOfArray(int array[],int length);
int main()
{
    //定义1个长度为3的数组
    int ages[]={425,1,992,90};
    
    //调用函数求最大值,传入数组长度参数
    printf("zuida值是%d\n",maxOfArray(ages,sizeof ages/sizeof(int)));
    return 0;

}

//定义一个函数求数组中的最大值,length为数组元素个数
int maxOfArray(int array[],int length)
{
    //sizeof array; 的结果在64位编译器下永远是8
    int max=array[0];
    for(int i=0;i<length;i++)
    {
        //先选定【0】为目标挨个去比较,谁大就换谁
        max=max<array[i]?array[i]:max;
    }
    return max;
}
(5)、二维数组

     二维数组是一个特殊的一维数组:它的元素是一维数组。其长度就是所有一维数组之和。


二、字符串

(1)、每个字符串的尾部有一个隐藏的字符'\0',ASCII码值是0,代表空。它是字符串的技术标记。

     C语言中木有String,字符串用字符数组来表示。

(2)、字符串的占位符是%s

#include <stdio.h>
int main()
{
    //字符串初始化
    /*
     下面两句的内存分布大体一致,当然地址值不同
     char name[10]={'i','t','\0'};
     char name[10]={'i','t',0};//\0的ASCII值就是0
     
     char name[10]="jack";//比较常用
     char name[]="sd";
     char name[10]={'i','t'};//也算是字符串,因为【2】之后都是默认为0
     
     char bane[]={'s','t'};//严格来讲这不是字符串,因为木有结束符0
     */
    
    char name[]="it";
    name[0]='l';
    printf("%lu\n",sizeof name);//结果是3,别忘了结束符0
    printf("name is %s\n",name);//占位符 %s
    
    
    char name2[]={'w','e'};
    //%s会从当前这个name2的首地址往外输出,至到遇到‘\0’为止
    printf("name2 is %s\n",name2);//所以此时输出结果为welt
    
    //结果是elt,因为此时将name2[1]的地址传给了%s,将从name2[1]开始输出直到遇见'\0'为止。
    printf("name2 is %s\n",&name2[1]);
    
    
    char name3[]="wer\0try";
    char name4[]={'a','s'};
    printf("name3 is %s\n",name3);//结果为wer
    printf("name4 is %s\n",name4);//结果为aswer
    
    return 0;
}
(3)、strlen函数

   该函数代表计算字符串长度,字节数,而不是字数。

   该函数从传入的字符串首地址开始计算,直到遇到'\0'为止,字节数不包含'\0'

   该函数声明在string.h文件中。

#include <stdio.h>
#include <string.h>
int main()
{
    char name[]="哈哈it";
    printf("字节数是%lu\n",strlen("wer\0try"));//结果为3
    printf("name字节数是%lu\n",strlen(name));//结果为8
    
    char name1[]={'2'};
    //从name1首地址开始计算,直到遇到0为止.所以会计算完name。
    printf("name1字节数是%lu\n",strlen(name1));//结果是9
    
    char c[]={0};
    printf("name1字节数是%lu\n",strlen(c));//结果是0
    
   
    return 0;
}


/*编写一个函数char_contains(char str[],char c),如果字符串str中包含字符c则返回数值1,
 否则返回数值0*/

#include <stdio.h>
#include <string.h>
int charConts(char array[],char c);
int charConts1(char array[],char c);

int main()
{
    char c[]="sdoiuiygsfsgvfdgbfrbf";
    
    printf("%d\n", charConts(c,'s'));
    printf("%d\n", charConts1("sdfghjk",'s'));
    
    
    return 0;
}

//方法一:利用strlen函数算字符串长度
int charConts(char array[],char c)
{
    for(int i=0;i<strlen(array);i++)
    {
        if(array[i]==c)
            return 1;
    }
    
    return 0;
}

//方法二:根据判断各角标位置上的元素是否为0来判断字符串长度
int charConts1(char array[],char c)
{
    int i=-1;
    while(array[++i])
    {
        if(array[i]==c)
            return 1;
    }
    return 0;
}
(4)、字符串数组

//几种初始化方式
    char names[2][10] = { {'J','a','y','\0'}, {'J','i','m','\0'} };
    char names2[2][10] = { {"Jay"}, {"Jim"} };
    char names3[2][10] = { "Jay", "Jim" };

三、指针

(1)、定义的格式
   类名标识符 *指针变量名;  比如:int *p
     指针就一个作用:能够根据一个地址值,访问对应的存储空间

#include <stdio.h>

int main()
{
    int a=10;
    
    //声明一个指针变量并进行初始化,此时p指向了变量a
    //数据类型int表示p只能指向该类型的变量
    //指针变量只能存储地址,前面的*只是一个象征,代表P是指针类型。
    int *p=&a;
    
    *p=89;//此时的*代表访问p指向的存储空间中的值
    printf("%d\n", a);//89
    
    a=90;
    printf("%d\n",*p);//90
    return 0;
}


/*
 	void change(int  n)函数调用完毕后,改变实参的值
 */

#include <stdio.h>
void change(int *n,int number);
int main()
{
    int a=10;
    change(&a,999);
    printf("%d\n",a);//999
    return 0;
}

void change(int *n,int number)
{
    //number代表要变成的值
    *n=number;
}
    定义变量int *p时的*仅仅是个象征,没有其他特殊含义,可以把(int *)看成是一个整体,也就是p的类型可以是 int *。*p=90;这的*是访问变量p指向的存储空间。

int **p;是个二级指针,就是指向指针的指针。

(2)、二级指针

#include <stdio.h>

int main()
{
    int a=10;
    int *p;
    p=&a;
    //二级指针
    int **p1=&p;
    //*(*p1)=*p=a
    **p1=34;
    printf("%d\n",a);//999
    return 0;
}
(3)、清空指针

p=0;或者p=null;

后者较专业

练习:

//定义一个函数同时实现和、差、乘积
#include <stdio.h>
int test(int i,int j,int *cha ,int *ji)
{
    *cha=i-j;
   // *ji=i*j;
    return i+j;
}

int main()
{
    int a=10;
    int b=7;
    int sum;
    int cha;
    int ji;
    sum=test(a,b,&cha,&ji);
         
    printf("sum---%d\ncha---%d\nji---%d\n",sum,cha,ji);
    return 0;
}

(4)、细节

#include <stdio.h>
int main()
{
    int a=2;
    char c=1;
    
    int *p=&c;
    //p是int类型的指针,此时c的地址赋给了p,所以*p会从c的地址开始读取4个字节
    printf("*p---%d\n",*p);//结果是513
    return 0;
}


指针p就从ffc4读到ffc7,一共4个字节,0000 0000 0000 0000 0000 0010 0000 0001=513.

赋值也是一样的道理,*p=10,也是从首地址读取4个字节进行赋值。








  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值