-
C基础第六天
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的几种用法,老师说今天讲的能懂就没事了,虽然能看到,但是心里还是没底,不知道能不能运用。
网友评论