C语言 循环和数组

一、循环结构

重复执行同一段代码,则选用循环结构

循环结构分类:While do...while  for

while和for:当型循环,至少执行0次

do..while::直到型循环,最少执行1次

1.1while循环

是当型循环,先判断,后执行,最少执行0次

格式1:

        表达式1;

        while(表达式2)//表达式2为真【非0】,则循环,表达式2为假【0】,则不循环

        {

        循环体;

        表达式3;

        }

格式2:

        去掉格式1的表达式3;

解析:例如:1-100

1> 表达式1:表示初始值

2>表达式2:循环条件【可以是任意表达式,一般选用关系,算术,逻辑】

3>表达式3:步长

4>while:循环函数,只能放在内部

5>while()后面不允许加分号

6>当只有一条语句时,大括号可以省略

7>死循环 while(1),没有步长

2>随机输入一个数,计算各个位数字之和
 1234567=1+2+3+4+5+6+7
int num, sum=0, count=0,t;
printf("请随机输入一个值: ");
scanf( "%d" , &num);
t=num;//使用t保存一下num的值
        while( num!=0)

        {
        sum+=num%10;//累加余数的和
        count++;
         num/=10;//步长
        }
printf("%d各个位数字之和是: %d ,%d位\n" ,t, sum, count);
return 0;

1.2 do....while循环

直到型循环,先执行,后判断,最少执行一次

格式1:

        表达式一;

        do

        {

                循环体;

                表达式3;

        }while(表达式2);//分号必须加,当表达式2成立【非0】则循环,不成立【0】,循环结束

格式2:

        do

        {

                循环体;

        }while(表达式2);//分号必须加

解析:

1>表达式1:表示初始值

2>表达式2:循环条件【可以是任意表达式,一般选用关系,算数,逻辑】

3>表达式3:步长

4>do..while  while后面必须加分号

5> 死循环do..while(1);

1.3 for循环

是当型循环,先判断,后执行,最少执行0次

格式:

        for(表达式1;表达式2;表达式3)

        {

                循环体;

        }

解析:

1>表达式1:初始值【可以是多个,多个之间使用,隔开】

2>表达式2:循环条件【可以是任意表达式,一般选用关系,算数,逻辑】可以是多个,使用运算符进行连接

3>表达式3:步长,可以是多个

4>当{}里面只有一条语句“{}”是可以省略的

5>表达式1,2,3均可以省略,但是分号不可以省略

6>死循环 for(;;)

1.4 goto

无条件跳转语句

格式:

        标识符:

        goto 标识符;

解析:

1>标识符:满足命名规范

eg:

int main(int argc,const char *argv[])
int a=1;
int i=0;
A:
        printf("bsisudh");
        printf("fghj");
                i++;
if(i==5)
                goto B;
printf("你好");
goto A;

B:
printf("结束\n");
return 0;
}

1.5 循环嵌套

* 1 1
** 2 2
***3 3
****4 4
 j==i   j<=i
for(int i=1;i<=n;i++)//外 曾循环控制行

{
for(int j=1;j<=i;j++)//内 存循环控制列

{
printf("*");
}
putchar(10);

}
 

**** 1 4
***  2 3
**    3 2
*      41
i+j=n+1  j<=n+1-i
for(int i=1;i<=n;i++)//外 曾循环控制行

{
        for(int j=1;j<=n+1- i;j++)//内存循环控制列
        {
        printf("*");

        }
 putchar(10);
 }

1.6循环跳转

1.6.1 break

break:中断,停止,用来跳出一层循环或者switch

适用于所有循环【while\do..while\for】,以及switch,break不可以单独使用在if语句中。

 1.6.2 continue

        作用:结束本次循环,进入下次循环

        场景:只可以用在循环【while\do..while\for】

for(int i=1;i<20;i++)//除了这几个数不打印,其余都打印 7 8 14 15
{
if( i%10==7| i%7==0)
continue;
printf("%d\n",i);
}
 

1.6.3 return

作用:返回,结束函数

二、数组

定义一个变量,只能储存一个数据,但是想要储存n个,那么定义n个变量不方便,引出数组

数组:使用连续的储存空间,存储类型相同的构造类型

构造类型:可以分割【数组、结构体、共用体】

2.1一维数组

只有一个下标表示的数组

2.2一维数组定义格式

格式:[存储类型] 数据类型 数组名 [常量表达式];

存储类型:

        auto:自动类型,一般默认不写就是自动类型

        static:静态类型,存储在静态区,延长生命周期

        const:修饰词,表示变量的值不可修改

        register:寄存器,访问速度快

        extern:外部变量

         volatile:防止内存优化

数据类型:

        int float double char short,结构体,共用体

数组名:命名规范

常量表达式:表示数组的个数【不为0,定义不为空,不为小数,初始化时不为变量】

int arr[0];

int arr[2.5];

int arr [ ];

int n=5;

int arr[n]={1,2,3,4,5};

错误

2.3一维数组初始化

初始化等价赋值

1>全局变量:在函数外定义的称为全局变量
全局变量未初始化的数组,默认结果是0
2>静态变量: static int arr[5];
静态变量数组未初始化,默认结果是0
3>局部变量数组未初始化,默认结果是随机值
4>全部初始化
int arr[5]={11,22,33 , 44, 55};
5>部分初始化:剩余元素默认以0填充
int arr[5]={11,22};
6>特殊初始化:在初始化时,可以省略数组长度,默认数组长度是实际元素的个数
int arr[]={11,22,33}; ===> int arr[3]={11,22,33};
7>错误的初始化
int arr[5];
arr={ 11 , 22,33 , 44,55};
 

2.4数组的引用

1>数组 下标从0开始,int arr[100]:0-99
2>越界访问, 例如int arr[100], 输出arr[100 ]
        2.1当越界访问的空间没有被占用,可以访问,输出垃圾值
        2.2当越界访问的空间被占用,不是重要的数据,可以访问,输出的数据没有意义
        2.3当越界访问的空间被占用,存储重要的数据,一旦访问,出现段错误
        段错误:访问了不该访问的内存空间

2.5数组的地址空间

1>数组名表示数组的首地址,也就是第一个元素的地址

arr=&arr[0]

数组名表示常量,不可以自增或者自减

2>地址的加减运算,表示地址的偏移

例如:int arr[4];

        &arr[0]+1:表示向高字节方向偏移数据类型大小

        &arr[0]-1:表示向低字节方向偏移数据类型大小

3>地址输出格式控制符是%p

 一维数组的练习:

 

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main(int argc, const char *argv[])
{
	char num=0;
	for(int i=0;i<6;i++){
		for(int j=0;j<=i-1;j++){
			putchar('_');
		}
		num='F';
		for(int k=0;k<=i;k++){
			putchar(num);
			num--;
		}
		putchar(10);
	}
	return 0;
}

2.输入一个数,判断这个数是含是完美数
完美数:除了本身,约数和等于本身
例如: 6:1+2+3=6 
28:1+2+7+4+14=28 

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

int main(int argc, const char *argv[])
{
	printf("请输入任意整数,判断是否为完美数");
	int num,sum=0;
	scanf("%d",&num);
	for (int i=1;i<num;i++){
		if(num%i==0){
			sum+=i;
		}
				}
	if(sum==num){
			printf("%d此数为完美数\n",num);
	}else{
			printf("抱歉,此数不是完美数,再输入一个吧~~\n");


	}
	return 0;
}

### C语言中结构体与数组之间的转换 在C语言中,结构体数组可以相互关联并进行操作。通过定义结构体数组或将结构体成员提取到普通数组中,能够实现两者间的灵活转换。 #### 定义结构体数组 可以通过如下方式定义一个包含多个学生信息的结构体数组: ```c struct stu { char *name; // 姓名 int num; // 学号 int age; // 年龄 char group; // 所在小组 float score;// 成绩 } class[5]; ``` 上述代码展示了如何声明一个名为`stu`的结构体以及基于该结构体的一个大小为5的数组`class`[^1]。 #### 将结构体成员存储至普通数组 如果希望将某个特定字段(如学生的成绩)从结构体数组中提取出来形成一个新的数值型数组,则可采用循环完成此过程: ```c #include <stdio.h> int main() { struct stu { char name[20]; int num; int age; char group; float score; }; struct stu students[] = {{"Alice", 1, 20, 'A', 89.5}, {"Bob", 2, 21, 'B', 78.0}, {"Charlie", 3, 19, 'A', 92.3}}; int n = sizeof(students)/sizeof(struct stu); float scores[n]; for (int i=0;i<n;i++) { scores[i] = students[i].score; } printf("Scores array:\n"); for(int j=0;j<n;j++){ printf("%.2f ",scores[j]); } } ``` 这段程序先构建了一个含有三个元素的结构体数组`students`,接着利用for循环把每位同学的成绩复制到了浮点数类型的`scores`数组里[^2]。 #### 使用指针数组处理结构体数据 当面对大量数据时,使用指针来管理内存可能更加高效。例如,在某些情况下对指向结构体的指针数组排序会比直接针对整个结构体数组排序更快一些[^3]。 以下是创建指向先前已有的`students`对象的指针数组示例,并对其进行简单冒泡排序按分数降序排列的过程: ```c #include <string.h> #include <stdlib.h> typedef struct student{ char name[20]; int id; double grade; }Student; void swap(Student **a, Student **b){ Student *temp=*a; *a=*b; *b=temp; } int compare(const void* a,const void*b){ return (*(double*)b - *(double*)a)>0?1:-1; } int main(){ Student slist[]={{"Tom",1,85},{"Jerry",2,92},{"Spike",3,76}}; size_t length=sizeof(slist)/sizeof(*slist); Student *pointers[length]; for(size_t k=0;k<length;++k){ pointers[k]=&slist[k]; } qsort(pointers,length,sizeof(Student*),compare); puts("\nSorted Students:"); for(size_t m=0;m<length;++m){ printf("%s %.2lf\n",(pointers[m])->name,(pointers[m])->grade); } } ``` 在这个例子中,我们首先建立了原始的结构体数组`slist`,之后又建立了一个同样长度但是保存的是这些结构体地址的指针数组`pointers`。最后通过对这个指针数组执行快速排序实现了间接对学生记录按照成绩高低重新安排顺序的目的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值