电商专业学习嵌入式软件开发第十一天

2017-01-17  本文已影响0人  雨打梨花闭门寒

C基础进行到第六天,我已经说不出来老师讲的具体是啥了,老师也看出我的吃力,结果今天下午就给我们几个基础薄弱的单独找老师补课,重新从最基础的内容讲起,虽说讲的基础都可以理解,但是对于应用还是没有自信。

一、结构体:我们自定义出来的一种数据类型。它里面的成员是我们常用的一些基本类型变量。
一般格式:
struct 结构体名
{
datatype data1;
datatype data2;
....
};

例:
struct student
{
    char name[20];
    char sex;
    int age;
};

这就是描述一个学生的数据类型。

特点:
1.定义的结构体只是个类型,使用的时候和其他的基本类型一样
2.{}后要有“;”
3.结构体里面的成员的名字可以和结构体同名

    struct test
    {
        int a;
        int test;
    };

4.定义的结构体不占内存,它只是个类型,用它定义的变量才占内存
5.结构体的定义允许嵌套,即机构体里面的成员是另一个结构体变量。

    例:
        struct date
        {
            int day;
            int month;
            int year;
        };
       struct student
       {
            char name[20];
            int age;
            struct date birthday;//定义了一个结构体变量。
       };

二、用结构体类型定义变量
1.先定义结构体类型,再定义变量
struct student //定义学生的数据类型
{
char name[20];
int age;
};

struct student  student1; //定义学生这个变量

2.在定义结构体类型的同时定义变量
struct student
{
char name[20];
int age;
}stu1,stu2; //在定义类型的同时定义了stu1,stu2 2个学生变量
struct student stu3;

3.无名结构体
struct //只能使用一次
{
char name[20];
int age;
}stu1,stu2;

访问结构体变量里面成员的方式:

例:
struct date
{
    int day;
    int month;
    int year;
};
struct student
{
    char name[20];
    int age;
    struct date birthday;
};
struct student stu1;
stu1.name
stu1.age
stu1.birthday.day
stu1.birthday.month
stu1.birthday.year

三、给一个结构体变量赋值
1.在定义的时候直接赋值(初始化)

#include <stdio.h>
struct student
{
    char name[20];
    int age;
};
void main()
{
    struct student stu1={"xxx",13};
    printf("%s %d\n",stu1.name,stu1.age);
}

2.先定义后赋值

#include <stdio.h>
#include <string.h>
struct student
{
    char name[20];
    int age;
};
void main()
{
    //char name[20];    name="asdfgh";
    struct student stu1;
    strcpy(stu1.name,"asdfgh");
    stu1.age=13;
    printf("%s %d\n",stu1.name,stu1.age);
}

3.用一个已知的结构体变量给同类型的结构体变量赋值

#include <stdio.h>
#include <string.h>
struct student
{
    char name[20];
    int age;
};
void main()
{
    struct student stu1={"xxx",1},stu2={"xxx",2};
//  if(stu1==stu2)  //不可以
//      printf("good\n");
//  else
//      printf("fail\n");
    
    stu1=stu2;   //可以,意外
    printf("%s %d\n",stu1.name,stu1.age);

    printf("%s %d\n",stu1); //不可以
}

定义的结构体变量的访问同定义数组相似,只能在初始化的时候给他整体赋值,即整体访问,其他任何时候都只能通过访问它的元素或成员去访问他,但是结构体变量有个例外,就是可以通过用一个同类型的变量去给另一个结构体变量赋值。

结构体变量的指针:一个指向结构体变量的指针

#include <stdio.h>
#include <string.h>
struct student
{
    char name[20];
    int age;
};
void main()
{
    struct student stu1,stu2={"xxx",1},*p;
    p=&stu2;
    printf("%s %d\n",p->name,(*p).age);
}

结构体数组:数组里面的每个元素都是结构体变量,每个元素都是相同数据类型的。

1.
struct student
{
    char name[20];
    int age;
}stu[3];

2.
struct student
{
    char name[20];
    int age;
};
struct student stu[3];

3.
struct
{
    char name[20];
    int age;
}stu[3]; 

访问数组里结构体元素的方式
stu[0].name
stu[0].age

练习:用结构体数组保存2个学生的个人信息,输入并输出

#include <stdio.h>
#include <string.h>
struct student
{
    char name[20];
    int age;
};
void main()
{
    int i=0;
    struct student stu[2];
    for(i=0;i<2;i++)
        scanf("%s %d",stu[i].name,&stu[i].age);
    for(i=0;i<2;i++)
        printf("%s %d\n",stu[i].name,stu[i].age);
}
#include <stdio.h>
#include <string.h>
struct student
{
    char name[20];
    int age;
};
void main()
{
    int i=0;
    struct student stu[2],*p;
    for(p=stu;p<stu+2;p++)
        scanf("%s %d",p->name,&p->age);
    for(p=stu;p<stu+2;p++)
        printf("%s %d\n",p->name,p->age);
}

练习:定义一个表示平面上点的数据类型,然后定义一个函数,输入的点和半径,判断该点是否在以原点为中心,以输入的半径为半径的圆内。

sqrt(x*x+y*y)      #include <math.h>    gcc 1.c -lm
#include <stdio.h>
#include <math.h>
int Incircle(struct Point,double);
struct Point
{
    double x;
    double y;
};
void main()
{
    struct Point p;
    printf("请输入点的位置:");
    scanf("%lf %lf",&p.x,&p.y);
    printf("请输入半径:");
    double r;
    scanf("%lf",&r);
    if(Incircle(p,r))
        printf("在园内!\n");
    else
        printf("在圆外!\n");
}
int Incircle(struct Point p,double r)
{
    double l=sqrt(p.x*p.x+p.y*p.y);
    if(l>r)
        return 0;
    else
        return 1;
}

typedef :给类型重命名

例:
typedef struct student
{
   char name[20];
   int age;
}STU;  //struct student <=> STU  给struct student 类型名重命名为STU   只是字符做了简单的替换
# define   S   100        // 宏定义 ,则S<=>100

内存:数据区 + 代码区 + 堆区(heap) + 栈区(stack)
数据区:分为静态数据区,常量区,全局数据区。静态变量,即static修饰的变量,放在静态区,const修饰的变量和常量放在常量区,我们定义的全局变量放在全局数据区。在数据区中的变量,通常没有初始化都会默认为0.

代码区:存放普通代码的区域

堆区(heap):就是用于手动开辟空间的内存区域,通常是由malloc/calloc/realloc/new这些函数进行开辟的,然后该空间由free/delete进行释放,它的生命周期取决于何时调用free/delete.

栈区(stack):主要是用于给局部变量开辟空间。

malloc(大小):用于在堆上面手动开辟空间
头文件:stdlib.h
该函数如果成功开辟空间后会把该段空间的首地址返回出来,默认是void *型,所以我们如果要把该地址赋给一个指针变量,则需要加类型转换。每次malloc并不一定总是成功的,所以通常需要判断,失败返回NULL.否则,成功。

例:
#include <stdio.h>
#include <stdlib.h>
void main()
{   
    int *p=(int *)malloc(sizeof(int));//在堆上面给一个整型数据开辟空间
    *p=10;
    printf("%d\n",*p);
    free(p);//在不用该段内存后,把p指针所指向的那段内释放掉
    p=NULL;//给指针置空,防止误操作
}

练习:手动分配一块内存给学生,输入学生的个人信息并输出。

#include <stdio.h>
#include <stdlib.h>
struct student
{
    char *name;
    int age;
    float score;
};
void main()
{
    struct student *p=(struct student *)malloc(sizeof(struct student));
    p->name="asdfg";
    p->age=13;
    p->score=91;
    printf("%s %d %.1f\n",p->name,p->age,p->score);
}

链表:

#include <stdio.h>
#include <stdlib.h>
struct node
{
    int data;
    struct node *next;
};
struct node * Create()
{
    int n,i;
    printf("要创建几个节点:");
    scanf("%d%*c",&n);
    struct node *head=(struct node *)malloc(sizeof(struct node));
    struct node *p=(struct node *)malloc(sizeof(struct node));
    printf("请输入数据:");
    scanf("%d%*c",&p->data);
    head->next=p;
    for(i=1;i<n;i++)
    {
        struct node *q=(struct node *)malloc(sizeof(struct node));
        printf("请输入数据:");
        scanf("%d%*c",&q->data);
        p->next=q;
        p=q;
    }
    p->next=NULL;
    return head;
}
void Print(struct node *head)
{
    struct node *p=head->next;
    while(p)
    {
        printf("%d\n",p->data);
        p=p->next;
    }
}
//头插
struct node *T_insert(struct node *head)
{
    struct node *q=(struct node *)malloc(sizeof(struct node));
    printf("请输入数据(头插):");
    scanf("%d",&q->data);
    q->next=head->next;  //先连q节点和首节点
    head->next=q;//再连q节点和头节点
    return head;
}
//尾插
struct node *W_insert(struct node *head)
{
    struct node *p=head->next;
    struct node *q=(struct node *)malloc(sizeof(struct node));
    printf("请输入数据(尾插):");
    scanf("%d%*c",&q->data);
    while(p->next)
    {
        p=p->next;
    }
    p->next=q;
    q->next=NULL;
    return head;
}
//中间插
struct node *Z_insert(struct node *head,int loc)
{
    struct node *q=(struct node *)malloc(sizeof(struct node));
    printf("请输入数据:");
    scanf("%d",&q->data);
    struct node *p=head->next;
    for(int i=1;i<loc;i++)
    {
        p=p->next;
    }
    q->next=p->next;
    p->next=q;
    return head;
}
void main()
{
    struct node *head=Create();
    Print(head);
    head=T_insert(head);
    Print(head);
    head=W_insert(head);
    Print(head);
    int loc;
    printf("在第几个节点后插入:");
    scanf("%d",&loc);
    head=Z_insert(head,loc);
    Print(head);
}

上面就是今天讲的C内容,到后面完全不知道讲啥了,还好有老师给我们补C基础。

#include<xxx.h>    //标准库文件
#include"xxx.h"   //自定义头文件
int main()
{
    //可执行代码
    return 0;
}
#include:预处理命令
stdio.h:C标准库头文件,例:math.h,string.h,stdlib.h,unistd.h……
<>;表示C库里面的头文件,"":用户自定义头文件
int main(int argc,char *argv[])
int:数据类型,表示整形数据类型,C++里面只能是int main()
main():表示函数,即主函数,一个C程序里面有且只有一个主函数,即整个源程序的执行入口
分三种情况:
int main():建议使用,不会报错
void main():大部分编译器都会通过,只有少数不会通过
main():虽然会报错,可以忽略
int argc,char *argv[]:形式参数(形参),
int argc:是一个整形变量表示传入main函数的参数的个数
char *argv[]:指针数组,表示传入main函数的参数的名称
main:函数名,同时也表示一个地址,
():形参列表
{}:表示一个代码块,此处表示的是:函数体
printf():函数调用,printf()是一个库函数,已在stdio.h中声明,直接引用即可
"hello,world\n":字符串常量
'\n':转义字符,表示换行,换到下一行行首
'\r':转义字符,表示换行,换到当前行行首
return 0:函数返回值,表示函数结束,返回0表示函数正确运行,返回非0表示函数运行错误
变量定义:
int 整型数据类型
    short int(short):短整型数据类型
    long int(long):长整型数据类型 
    unsigned:无符号数,一般指大于0的数
    signed:有符号数,一般指负数
char 字符型数据类型
    字符:由单引号引起来的单个字母,数字或其他符号
    如:'a','3','A','?','\'
    ASCII值:
    整型数据和字符型数据相互赋值的情况
float 实型数据类型,浮点型数据类型,单精度数据类型,有效位数7位左右
double 双精度型数据类型,有效位15位左右
    float和double都表示小数
printf:按格式输出-----print,format
1)printf("要输出的内容");
2)printf("格式/占位符",表达式);
printf("%5d",a):右对齐
printf("%-5d",a):左对齐

gcc xx.c -wall显示所有警告
=:左右两边的空格可有可无,回车都可以

老师说警告可以忽略,错误不能忽略,但是针对指针的警告不能忽略,最好不要有警告

今天下午讲的主要是printf的几种用法,老师说今天讲的能懂就没事了,虽然能看到,但是心里还是没底,不知道能不能运用。

上一篇下一篇

猜你喜欢

热点阅读