目录
循环结构
for while
for循环:
for(表达式1;表达式2;表达式3)
{
代码段;
}
表达式1:赋初值
表达式2:终止条件
表达式3:增值或减值
int i;
for(i=0;i<4;i++)
{
printf("%d ",i);
}
printf("i=%d ",i);
变形:
int i=0;
for(;i<4;i++)
{
printf("%d ",i);
}
int i=0;
for(;i<4;)
{
printf("%d ",i);
i++;
}
int i=1;
for(;;){};
嵌套结构
int i,j;
for(i=0;i<5;i++)
{
for(j=0;j<3;j++)
{
printf("i=%d j=%d\n",i,j);
}
}
//外层循环执行一次,内层循环执行一轮
练习:九九乘法表
int i,j;
for(i=1;i<10;i++)
{
for(j=1;j<=i;j++)
{
printf("%d*%d=%2d ",i,j,i*j);
}
printf("\n");
}
int a=2,b=22,c=222;
printf("%3d\n",a);
printf("%3d\n",b);
printf("%3d\n",c);
练习:
1.打印水仙花数 如:153=1^3+5^3+3^3 100-999
2.
while循环:
int i=0;
while(i<4)
{
printf("%d ",i);
i++;
}
//死循环:while(1){}
do...while
do
{
语句块;
增值或减值;
}while(终止条件)
while:先判断,再执行
do...while:先执行一次,再判断
练习:
循环控制语句
break continue
break:直接结束循环
continue:结束本次循环,继续下一次循环
int i;
for(i=1;i<10;i++)
{
if(i%2==0)
{
printf("qqqq-%d\n",i);
// continue;
// break;
return 0;
}
printf("wwww-%d\n",i);
}
printf("eeeee\n");
return 0;
练习:
1.从终端上输入一个字符并在终端上输出这个字符,当输入字符为‘q’时,程序结束。
2.循环输入一个5位数,判断它是不是回文数。当输入0时循环结束。
即12321是回文数,个位与万位相同,十位与千位相同
3.
打印以下图案:
要求行数从终端输入。
输入:5
*
**
***
****
*****
*****
****
***
**
*
数组
多个同种数据类型变量的集合
特点:
内存连续开辟
同种数据类型
一维数组
格式:
存储类型 数据类型 数组名[元素个数]
int a[5];
访问: 访问时,下标从0开始
例:int a[5]={2,3,4,5,6};
a[0]----->第一个元素
a[1]----->第二个元素
a[2]----->第三个元素
a[3]----->第四个元素
a[4]----->第五个元素
注意数组越界问题:访问时超过设置的空间
int a[5]={2,3,4,5,6};
char b[5]={'q','w','e','r','t'};
//*********************************
char c[5]={97,98,99,100,101};
printf("%c %c\n",c[0],c[1]);
数组名也是数组首地址,是地址常量,不能为左值(=左边)
int a[5]={2,3,4,5,6};
printf("%p %p\n",a,&a[0]);
初始化
全部初始化
int a[5]={2,3,4,5,6};
部分初始化
int a[5]={2,3}; //2 3 0 0 0
int c[33]={};
未初始化部分值为0
未初始化
int a[5]; //值为随机值
a[0]=5;
a[1]=3;
a[2]=4;
练习:
注意,数组越界,有时编译器不会报错。
数组的内存分配(int型):
循环遍历
int a[5]={1,2,3,4,5};
for(int i=0;i<5;i++)
printf("%d\n",a[i]);
int a[5]={1,2,3,4,5};
for(int i=0;i<5;i++)
printf("%p\n",&a[i]);
数组大小
int a[5]; //4*5=20
char b[33]; //33*1=33
1.元素个数*数据类型大小
2.sizeof(a);
练习:计算斐波那契数列前15项并逆序输出
1 1 2 3 5 8 13
int a[15]={1,1};
int a[15]={1,1};
for(int i=2;i<15;i++)
a[i]=a[i-1]+a[i-2];
for(int i=14;i>=0;i--)
printf("%d ",a[i]);
清零函数
头文件:#include <strings.h>
void bzero(void *s, size_t n);
功能:将数组的内存空间的值设置为0
参数:数组的首地址 n:字节大小
返回值:无
使用方法:
int a[15]={1,1,2,3,4,5,6};
bzero(a,sizeof(a));
for(int i=0;i<15;i++)
printf("%d ",a[i]);
memset
头文件:#include <string.h>
void *memset(void *s, int c, size_t n);
功能:清空数组
参数:数组的首地址 c:要设置的值 n:字节大小
返回值:数组首地址
注意:memset是按字节设置对应值的,比如,一个int类型的数组,一个元素对应4字节,如果要用memset将其中的元素设置9这个值,得到的结果是每个元素的4字节对应的全是9的单字节值,将元素右移24位即可得到正确的值。
int a[5]={1,2,3,4,5};
memset(a,0,sizeof(a));
for(int i=0;i<5;i++)
printf("%d ",a[i]);
memset按字节赋值,1-》int 4字节 1字节=8位 0000 00010000 00010000 00010000 0001
练习:
- int a[10]={}; 去掉其中最大值和最小值,求平均值。
字符数组
字符数组存放字符串
元素的数据类型是字符型的数组
char a[4]={"abc"}; //sizeof(a)=4
char b[4]="abc"; //sizeof(a)=4
char c[]="abc"; //sizeof(a)=4
char d[]={'a','b','c'}; //sizeof(a)=3
char e[33]="abc"; //sizeof(a)=33
字符数组的输入输出
char a[33]={};
***********************************
for(int i=0;i<5;i++)
scanf("%c",&a[i]);
for(int i=0;i<5;i++)
printf("%c",a[i]);
scanf("%s",a);
printf("out:%s\n",a);
输入的字符串不能有空格;因为scanf输入字符串时遇到空格或\n都会认为字符串输入结束,空格后边的内容不会存放到数组里。
scanf("%[^\n]",a);
gets puts
char *gets(char *s);
功能:从终端输入字符串
参数:字符数组的首地址
返回值:字符数组的首地址
int pi int puts(const char *s);
功能:从终端输出字符串
参数:字符数组首地址
返回值:输出字符的个数
gets(a);
puts(a);
练习:输入一串字符,计算其中空格个数
判断:
char s[10]={};
- s[10]="hello"; //错误
- s="hello"; //错误 s是数组名也是首地址,是地址常量,不能为左值(=左边)
- strcpy(s,"hello"); //对
练习:
1.
D
2.
3.
把一串字符串进行倒置"hello"---"olleh"
示例:
4.
在终端输入大写字母、小写字母、空格、数字,分别在终端输出他们的个数
示例:
计算字符串实际元素个数
1.遍历字符串:
2.strlen函数
#include <string.h>
size_t strlen(const char *s);
功能:计算字符串实际元素个数
参数:字符串首地址
返回值:实际元素个数
实列:
sizeof和strlen的区别:
- sizeof是关键字,strlen是个函数
- sizeof是计算数据实际开辟的空间大小,strlen计算字符串的实际元素个数
- sizeof计算包括'\0',strlen计算不包括'\0';省略数组元素个数的情况下,sizeof比strlen多1
示例:
冒泡排序
#include<stdio.h>
#define N 5
int main(int argc, char const *argv[])
{
int a[N]={},t;
for(int i=0;i<N;i++)
scanf("%d",&a[i]);
for(int i=0;i<N-1;i++)
{
for(int j=0;j<N-1-i;j++)
{
if(a[j]>a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
return 0;
}
选择排序
交换原理:n个数,先找出最小值的下标暂存(初始化假设第一个值),把假设的第一个值分别和每一个值进行比较,如果中途遇见更小的值,对索引重新赋值,直到本轮循环结束,把最小的值和第1个数交换
#include<stdio.h>
#define N 5
int main(int argc, char const *argv[])
{
int a[]={1,4,3,2,11},t,k;
for(int i=0;i<4;i++)
{
k=i;
for(int j=i+1;j<5;j++)
{
if(a[k]>a[j])
k=j;
}
if(i!=k)
{
t=a[i];
a[i]=a[k];
a[k]=t;
}
}
return 0;
}
二维数组
格式:
存储类型 数据类型 数组名[行数][列数]
int a[2][3];
访问元素:数组名[行下标][列下标];(下标从0开始)
a[0][0] | a[0][1] | a[0][2] |
a[1][0] | a[1][1] | a[1][2] |
行下标、列下标都不能越界
int a[2][3]={2,5,6,9,8,7};
int a[2][3]={{2,5,6},{9,8,7}}; //按行进行赋值{ { },{ } }
printf("%d %d %d\n",a[0][0],a[0][2],a[1][2]);
int a[][3]={2,5,6,9,8,7};//可以省略行数
int a[2][]={2,5,6,9,8,7};//错误
练习:
答案:D
二维数组大小
行数*列数*数据类型大小
数组名:
int a[2][3]={2,5,6,9,8,7};
a:第一行的行地址
a+1:第二行的首地址
初始化
//全部初始化
int a[2][3]={2,5,6,9,8,7};
int a[2][3]={{2,5,6},{9,8,7}}; //按行进行赋值{ { },{ } }
//部分初始化:未被赋值的元素值为0
int a[2][3]={2,5};//2 5 0 0 0 0
int a[2][3]={{2},{9,8}}; //2 0 0 9 8 0
int a[2][3]={ };
//未初始化:值为随机值
int a[2][3];
a[0][0]=5;
a[0][1]=2;
练习:
答案:A C B
内存分配
int a[2][3]={2,5,6,9,8,7};
地址 | 值 | 元素 | ||
a[0] | a | &a[0][0] | 2 | a[0][0] |
a[0]+1 | &a[0][1] | 5 | a[0][1] | |
a[0]+2 | &a[0][2] | 6 | a[0][2] | |
a[1] | a+1 | &a[1][0] | 9 | a[1][0] |
a[1]+1 | &a[1][1] | 8 | a[1][1] | |
a[1]+2 | &a[1][2] | 7 | a[1][2] |
循环遍历
练习:有一个3x4的矩阵(元素值不相同),要求输出其中最大值以及它的行号和列号
练习:
猴子吃桃问题:猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾,又多吃了一个,第二天早上又将剩下的桃子吃掉一半,又多吃了一个。
以后每天早上都吃了前一天剩下的一半零一个。到第10天早上想再吃时,见只剩下一个桃子了。求第一天共摘了多少。
示例:
练习:
打印杨辉三角形的前十行
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1
1 6 15 20 15 6 1
...