发布时间:2023-03-20 10:30
do
{
//循环体
}while(表达式);
//和while唯一的区别就是,先执行一次循环体,然后再判断表达式
//注意: 最后while 有一个分号 ;
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(;;)//里面表示式可以不写,但是两个分号必须得写
{
}
是对于基本类型得一种应用,是给用户使用的;基本类型对于物体的描述比较单一,构造类型可以对物体有跟多的描述;
构造类型有三种,分别是 数组、结构体、共用体
数组是用来保存一组相同类型的数据的顺序集合;
数组中保存的每一个数据都叫做数组的一个元素;
数组需要在内存中开辟一块连续的空间,每个元素之间的地址都是连续的;
我们只讲一维数组,所谓的一维数组,就是说只有一个下标的数组;
(存储类型) 数据类型 数组名[下标];
存储类型:默认是auto
数组中元素的类型可以是基本类型,也可以是构造类型(除数组);
数组名:是一个标识符,必须符合标识符的命名规范;
下标:在定义数组的时候,只是一个常量,表示的是数组的长度;在使用数组的时候,下标表示数组的第几位(从0开始),可以是常量,也可以是变量,还可以是一个能够算出结果的表达式;
#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;
}
#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;
}
概念:内存中每个字节的空间都有一个编号,这个编号就叫做地址,也叫做指针;也就是说指针其实就是地址编号,专门用来保存指针的变量,就是指针变量,我们平时说的指针,就是指针变量,地址编号叫做地址;
格式:
数据类型 *指针变量名;(一定要初始化)
注意事项:
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;
}
#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;
}
关键字 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;
}
概念:将能够实现一定功能的代码块封装成一个整体,这个整体就是函数,每次使用这些代码块的时候,只需要调用相应的函数即可;
格式:
返回值类型 函数名(形参列表)
{
//函数体;
}
注意:如果说没有返回值,返回值类型填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;
}