从0开始的C语言入门教程day2(完结,让你0基础两天学会C语言)

发布时间:2023-03-20 10:30

一、循环结构

1、do while循环

do
{
    //循环体
}while(表达式);
//和while唯一的区别就是,先执行一次循环体,然后再判断表达式
//注意:  最后while 有一个分号 ;

2、for循环

for(表达式1;表达式2;表达式3)
{
    //循环体
}
//先执行表达式1,表达式1 一般为赋值语句,或者是定义变量
//再执行表达式2,表达式2 为判断语句,如果表达式2为真,执行循环体,如果表达式2为假,结束循环;
//执行完表达式2,再执行表达式3;完事儿之后,接着判断表达式2,
//如果表达式2依旧为真,还执行表达式3...2、3循环,知道表达式2为假,结束循环
//表达式3,一般为步长;改变循环变量的值;

练习:
使用for 循环实现1~100 的累加,并输出结果;

#include 
int main(void)
{
  int i,sum = 0;
    for(i = 100;i > 0;i--)
    {
        sum += i;
    }
    printf("sum = %d i = %d\n",sum,i);
    return 0;
}

死循环的写法
所谓的死循环,就是说条件一直不满足,循环不退出的情况;

while(1){}

for(;;)//里面表示式可以不写,但是两个分号必须得写
{
}

二、构造类型

是对于基本类型得一种应用,是给用户使用的;基本类型对于物体的描述比较单一,构造类型可以对物体有跟多的描述;
构造类型有三种,分别是 数组、结构体、共用体

1、数组

1.1概念:

数组是用来保存一组相同类型的数据的顺序集合;
数组中保存的每一个数据都叫做数组的一个元素;
数组需要在内存中开辟一块连续的空间,每个元素之间的地址都是连续的;
我们只讲一维数组,所谓的一维数组,就是说只有一个下标的数组;

1.2格式

(存储类型) 数据类型 数组名[下标];
存储类型:默认是auto
数组中元素的类型可以是基本类型,也可以是构造类型(除数组);
数组名:是一个标识符,必须符合标识符的命名规范;
下标:在定义数组的时候,只是一个常量,表示的是数组的长度;在使用数组的时候,下标表示数组的第几位(从0开始),可以是常量,也可以是变量,还可以是一个能够算出结果的表达式;

1.3、一维数组的访问及相关性质

#include 
int main(void)
{
    //定义了一个数组名为str1的数组,数组里面有5个 int 类型的数据;
    int str1[5];
    int str2[5];
    int i;
    //对数组赋值
    str1[0] = 10;
    str1[1] = 20;
    str1[2] = 30;
    str1[3] = 40;
    str1[4] = 50;
    //读取数据
    printf("str[0] = %d\n",str1[0]);
    printf("str[1] = %d\n",str1[1]);
    printf("str[2] = %d\n",str1[2]);
    printf("str[3] = %d\n",str1[3]);
    printf("str[4] = %d\n",str1[4]);
    //一维数组中的元素地址连续
    //打印地址 %p, &可以获取变量的地址;
    printf("str[0] = %p\n",&str1[0]);
    printf("str[1] = %p\n",&str1[1]);
    printf("str[2] = %p\n",&str1[2]);
    printf("str[3] = %p\n",&str1[3]);
    printf("str[4] = %p\n",&str1[4]);
    //一维数组的遍历
    for(i = 0;i < 5;i++)
    {
        printf("str1[%d] = %d\n",i,str1[i]);
        //注意:下标不要越界;
        //如果越界,编译器不会检查错误,但是一旦访问到非法内存,就会出现错误
    }
    //一维数组所占内存的大小
    printf("sizeof(str1) = %d\n",sizeof(str1));
    //有可能不确定数组元素的个数,怎么遍历
    for(i = 0;i < sizeof(str1) / sizeof(int);i++)
    {
        printf("str1[%d] = %d\n",i,str1[i]);
    }
    //数组名是一个地址,并且是数组所有元素的首地址
    //地址是一个常量,所以数组名不能够被赋值,更不能做 str1++ 操作


    //如果数组已经定义好了,就不能通过数组名直接整体赋值
    for(i = 0;i < 5;i++)
    {
        str2[i] = str1[i];
        printf("str2[%d] = %d\n",i,str2[i]);
    }
    return 0;
}

1.4、一维数组的初始化

#include 
int main(void)
{   //在定义的时候
    //数组的完全初始化
    //如果数组中元素没有初始化,那么里面的值就是随机值
    int s[5] = {10,20,30,40,50};
    //完全初始化为 0
    int s2[5] = {0};
    //不完全初始化
    //未被初始化的元素会被默认初始化为0
    int s3[5] = {10,20};
    //不在定义的时候,不能够用花括号初始化
    return 0;
}

练习:
定义一个10个长度的数组,并且完全初始化,编写代码,找出数组中最大的元素及其下标;

#include 
int main(void)
{
    int s[10] = {12,34,54,87,77,44,76,9,66,10};
    int max_index = 0;//假设第0 位为最大的元素
    int i;
    for(i = 1;i < 10;i++)//i 从第1 位开始,是自己不参与比较的意思
    {
        if(s[i] > s[max_index])
        {
            max_index = i;
        }
    }
    printf("max_num : %d max_index: %d\n",s[max_index],max_index);
    return 0;
}

2、指针

概念:内存中每个字节的空间都有一个编号,这个编号就叫做地址,也叫做指针;也就是说指针其实就是地址编号,专门用来保存指针的变量,就是指针变量,我们平时说的指针,就是指针变量,地址编号叫做地址;

格式:
数据类型 *指针变量名;(一定要初始化)

从0开始的C语言入门教程day2(完结,让你0基础两天学会C语言)_第1张图片
注意事项:
1、* 号,在定义指针的时候,只起到标识作用,目的是为了和普通变量区分开
2、p 才是指针;
3、* 号,在使用的时候,表示的是取到所保存地址上的值;
*p 和 a 是等价的;
4、指针在定义的时候,一定要初始化,指针的出现,必须指向某处,或者指向NULL,否则他就会瞎指,这种情况被称为野指针,野指针是有害的;

#include 
int main(void)
{
    //内存中每个字节都有一个编号,叫做地址
    //定义变量时,系统会根据变量的类型给变量分配合适大小的空间用来保存数据
    int a = 10;
    //使用 & 获取变量a 的地址
    int *p = &a;//用a 的地址初始化指针 p
    printf("&a = %p\n",&a);//打印地址用 %p
    printf("p = %p\n",p);//指针里面存储的是地址,所以用%p 打印
    //常量 是没有地址的
    //int *p2 = &100;//错误
    printf("&p = %p\n",&p);//指针的地址,和变量a 的地址没有关系,使用单独的内存存储指针
    printf("a = %d *p = %d\n",a,*p);//对指针取 * 操作,可以取到所存地址上的值
    *p = 20;//通过*p 修改变量的值,当指针 p 指向 a 所在的内存时,*p等价于变量 a;
    printf("a = %d *p = %d\n",a,*p);


    //指针只能保存已经分配好的地址,不能够自己分配
   /* int b = 100;
    int *q = &b;
    *q = 200;//这种写法没有问题,因为b 所在的内存,已经被分配给他了


    int *q2 = 0x12345678;
    *q2 = 200;//不可以这样写,非法访问
    */
    printf("psize = %d\n",sizeof(p));//指针的大小固定,在32位系统中是4个字节,在64位系统中是8个字节;
    return 0;
}

3、指针和数组之间的关系

#include 
int main(void)
{
    int s[6] = {10,20,30,40,50,60};
    int i;
    printf("s[0] = %d\n",s[0]);
    printf("s[3] = %d\n",s[3]);
    //数组名就是一个地址,是数组的首地址
    //通过下标访问数组成员的本质,就是以数组名(首地址)为基准,偏移几个数据元素,然后取值;
    printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
    printf("s = %p   *s = %d\n",s,*s);
    printf("s+3 = %p   *(s+3) = %d   s[4] = %d\n",s+3,*(s+3),s[4]);
    printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
    int *p = s;//将数组的首地址(数组名)赋给指针 p;
    int *p2 = &s[0];
    //int *p3 = &s;//不要使用,有问题
    printf("p = %p  p2 = %p\n",p,p2);
    //这三种方法都可以取到首地址
    //当指针保存了数组的首地址之后
    // s[i] <==> *(s+i) <==> *(p+i) <==> p[i]
    printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
    printf("p = %p  *p = %d\n",p,*p);
    printf("p+3 = %p   *(p+3) = %d  p[4] = %d\n",p+3,*(p+3),p[4]);
    printf("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
       for(i = 0;i < 6;i++)
       {
           //printf("s[%d] = %d\n",i,s[i]);
           //printf("s[%d] = %d\n",i,p[i]);
           //printf("s[%d] = %d\n",i,*(s+i));
           printf("s[%d] = %d\n",i,*(p+i));
       }
       //p 是指针变量,所以可以被赋值,p = p + 1;意思是说 指针向后偏移一位;
       //
       p++;//偏移的是一个数据类型
       printf("*p++ = %d\n",*p);
       //s++;// s 是一个地址常量,不可以被赋值;
    return 0;
}

练习:
使用指针,实现计算字符串的长度;

#include 
int main(void)
{
    char str[128] = {0};
    char *p = str;
    int count = 0;
    printf("please input  string >> ");
    scanf("%s",str);
    while(*p != '\0')// *p 是字符串的第一个字符
    {
        p++;//指针的指向向后偏移一位;
        count++;//计数 +1
    }
    printf("slen = %d\n",count);
    return 0;
}

练习: 实现字符串的拼接;将字符串str2 接到str1 后面;
str1[] = “hello”;
str2[] = “world”;

str1[] = “helloworld”;
// str[] = “hello world”;

#include 
int main(void)
{
    char str1[128] = {0};
    char str2[128] = {0};
    char *p = str1;
    char *q = str2;
    printf("please input str1 >> ");
    //scanf("%s",str1);
    gets(str1);
    printf("please input str2 >> ");
    //scanf("%s",str2);
    gets(str2);
    while( *p != '\0')
    {
        p++;
    }//先找到str1 的 '\0'
    while(*q != '\0')
    {
        *p++ = *q++;
        //*p = *q;
        //p++;
        //q++;
    }//将str2 按字符赋给 str1
    *p = *q;
    //将 str2 的 '\0' 赋给 str1
    printf("str1 = %s\n",str1);
    return 0;
}

4、结构体

关键字 struct
概念:是一种包含多个不同数据类型的数据的类型;

格式
struct 结构体名
{
    类型1 成员1;
    类型2 成员2;
    类型3 成员3}//注意:类型可以不同,也可以相同;
//结尾有个 分号 ;
#include 
#include 

int main(void)
{
    //定义一个学生的结构体类型
    //第一种方法
   /* struct student
    {
        char name[20];
        int age;
        int score;
    };
    //定义变量的方法有两种
    //1,定义一个普通的结构体变量
    struct student s1;
    //普通结构体变量访问成员,并且赋值
    //使用 . 访问
    s1.age = 18;
    s1.score = 18;
    //s1.name = "zhangs";
    //strcpy 赋值函数
    strcpy(s1.name,"zhangs");
    printf("%d\n",s1.age);
    printf("%d\n",s1.score);
    printf("%s\n",s1.name);
    //2.定义一个结构体指针变量
    struct student *p = &s1;
    //结构体指针变量访问成员并赋值
    //使用 -> 访问
    p->age = 20;
    p->score = 16;
    strcpy(p->name,"zhangs");
    printf("%d\n",p->age);
    printf("%d\n",p->score);
    printf("%s\n",p->name);
    */
    //第二种定义结构体类型的方法
    //借助 关键字 typedef 作用:起别名
    typedef struct student
    {
        char name[20];
        int age;
        int score;
    }stu_t;
    stu_t s1;
    s1.age = 22;
    s1.score = 99;
    strcpy(s1.name,"zhangs");
    printf("%d\n",s1.age);
    printf("%d\n",s1.score);
    printf("%s\n",s1.name);
    return 0;
}

练习:定义一个学生结构体,包含学生的基本信息,(姓名,学号,年龄,分数),在终端录入学生信息,录完之后,将信息全部输出;

#include 
int main(void)
{
    struct student
    {
        char name[20];//结构体类型里面一定不要初始化
        int id;
        int age;
        int score;
    };
    while(1)
    {
        struct student stu;
        printf("请输入学生的姓名:");
        scanf("%s",stu.name);
        printf("请输入学生的学号:");
        scanf("%d",&stu.id);
        printf("请输入学生的年龄:");
        scanf("%d",&stu.age);
        printf("请输入学生的成绩:");
        scanf("%d",&stu.score);
        printf("该学生的信息为:\n姓名:%s\t学号:%d\n年龄:%d\t成绩:%d\n",stu.name,stu.id,stu.age,stu.score);
    }
    return 0;
}

5、函数

概念:将能够实现一定功能的代码块封装成一个整体,这个整体就是函数,每次使用这些代码块的时候,只需要调用相应的函数即可;

格式:
返回值类型 函数名(形参列表)
{
    //函数体;
}
注意:如果说没有返回值,返回值类型填void ,没有形参列表,可以空着或者填void
函数的三要素,声明,实现,调用;
//函数的声明
int add(int a,int b);
//函数的实现
int add(int a,int b)
{
    int c;
    c = a + b;
    return c;
} 
//函数的实现不能够写在main 函数中;
int main(){
    int x = 20;
    int y = 30;
    int z;
    //函数的调用
    z = add(x,y);                
}

练习:
封装一个函数,实现 1 ~ n 累加的和,返回和值;

#include 
int madd(int n)
{
    int tempsum = 0;
    while(n > 0)
    {
        tempsum += n--;
    }
    return tempsum;
}
int main(void)
{
    int x,sum;
    while(1)
    {
        printf("please input num >> ");
        scanf("%d",&x);
        sum = madd(x);
        printf("sum = %d\n",sum);
    }
    return 0;
}

函数补充:
练习:
封装函数,实现计算字符串的长度;

#include 
int mstrlen(char *s)
{
    int templen = 0;
    char *p = s;
    while(*p != '\0')
    {
        p++;
        templen++;
    }
    return templen;
}
int main(void)
{
    char str[128] = {0};
    int len;
    while(1)
    {
        printf("please input string >> ");
        scanf("%s",str);
        len = mstrlen(str);
        printf("mlen = %d\n",len);
    }
    return 0;
}

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号