目录
数组
一维素组
- 定义:基类型 a[b];
- a为数组名;b为数组长度,数组下标从0开始,取不到b
- 不能用变量来定义数组长度:int a[n];
- 使用宏定义可以:int a[N];N已定义
- 占内存字节数:数组长度*sizeof(基类型)
数组初始化
int a[5]={60,1,4,1};//花括号元素个数不能超过数组长度
int a[]={1,2,3}//根据花括号元素个数来确定数组大小
- 通过**memset(a,0,sizeof(a));**初始化
- sizeof(a)获取数组a所占内存字节数
- 记得开头加#include<string.h>
元素访问
- 数组名[下标]
- 允许下标是整型变量或表达式
元素赋值
- 通过循环语句赋值
int i;
for(i=0;i<4;i++)
{
b[i] = a[i]
}
- 通过mencpy赋值
- 记得开头加#include<string.h>
memcpy(b,a,sizeof(a));//数组a复制给数组b
二维数组
定义和初始化
- 按行存放
定义:基类型 a[b][c];//三维数组:基类型 a[b][c][d];n维数组依此类推
int a[2][3]//表示2行3列
int a[][4]={1,2,3,4,5,6,7,8,9,10,11,12}//第二位长度不能省略
int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}//等价第一行代码
int a[][4]={{1,2,3},{4,6},{6}}//大花括号内的小花括号代表某行,4代表列数,即一行最多存储4个数
int a[][4]={{1,2,3,0},{4,6,0,0},{6,0,0,0}}//等价第三行代码
int a[3][]={1,2,3}//写法错误,不能判断几行几列
#include<stdio.h>
int main()
{
int i,j;
int a[2][3] = {1,2,3,4,5,6};
for(i=0;i<2;i++)//行判断
{
for(j=0;j<3;j++)//列判断
{
printf("%d ", a[i][j]);
}
printf("\n");
}
return 0;
}
原则
- 不要数组下标越界
- 字符数组要留意"\0"
向函数传递数组
- 数组作为函数参数:实参数组和形参数组占据同一存储单元
- 传递地址
传递一维数组
#include<stdio.h>
#define N 40
int Average(int score[],int n);
void ReadScore(int score[],int n);
int main()
{
int score[N],aver,n;
printf("Input n:\n");
scanf("%d",&n);
ReadScore(score,n);
aver = Average(score,n);//用不带下标的数组名作为函数实参,不需要方括号
printf("Average score is %d\n",aver);
return 0;
}
void ReadScore(int score[],int n)//输入n位学生成绩
{
int i;
printf("Input score:\n");
for(i=0;i<n;i++)
{
scanf("%d",&score[i]);
}
}
int Average(int score[],int n)//计算平均分
{
int i,sum=0;
for(i=0;i<n;i++)
{
sum += score[i];
}
return sum/n;
}
- 用不带下标的数组名作为函数实参
传递二维数组
- 声明二维数组形参时,不能省略数组第二维长度
- 元素地址:首地址+偏移量
int AverforStud(int score[][COURSE_N],int sum[],float aver[],int n)//计算每门课程平均分
{
int i,j;
for(j=0;j<COURSE_N;j++)//遍历每门课程
{
sum[j]=0;//第j门课程总分
for(i=0;i<n;i++)//遍历每个学生
{
sum[j]=sum[j]+score[i][j];
}
aver[j]=(float)sum[j]/COURSE_N;
}
}
int AverforStud(int score[][COURSE_N],int sum[],float aver[],int n)//计算每个学生的平均分
{
int i,j;
for(i=0;i<n;i++)//遍历每个学生
{
sum[i]=0;//第i个学生总分
for(j=0;j<COURSE_N;j++)//遍历每门课程
{
sum[i]=sum[i]+score[i][j];
}
aver[i]=(float)sum[i]/COURSE_N;
}
}
算法
查找算法
线性查找
二分查找
排序算法
冒泡排序
- 比较相邻两个数据,顺序不对,则将其位置交换
void BubbleSort(int score[],int n)//排序算法(升序)
{
int i,j,temp;
for(i=0;i<n-1;i++)
{
for(j=1;j<n-1;j++)
{
if(score[j]<score[j-1])//交换相邻元素
{
temp = score[j];
score[j] = score[j-1];
score[j-1] = temp;
}
}
}
}
交换排序
- 将第1个数与后面数进行比较,然后交换位置,然后第二个数开始比较
void ChangSort(int score[],int n)//交换法升序
{
int i,j,temp;
for(i=0;i<n-1;i++)//
{
for(j=1+i;j<n;j++)
{
if(score[j]<score[i])//两个元素比较
{
temp = score[j];
score[j] = score[j-1];
score[j-1] = temp;
}
}
}
}
选择法排序
- 在每一遍比较中,在剩余的待比较的数中选择一个最小的数与这个剩余序列的第一个数交换位置
void SelectionSort(int score[],int n)//交换法升序
{
int i,j,temp;
for(i=0;i<n-1;i++)//第i个位置的元素
{
k=i;
for(j=1+i;j<n;j++)//寻找最低分所在下标k的过程
{
if(score[j]<score[k])
{
k = j;//记录最小数的下标位置
}
if(k != i)//最小数不在下标位置
{
temp = score[j];
score[j] = score[j-1];
score[j-1] = temp;
}
}
}
}
字符串
字符串输入输出
用scanf()输入
- 不能输入带空格的字符串
- %s:输入字符
- 不读走回车,留在缓冲区中
#include <stdio.h>
#define STR_LEN 80
int main()
{
char str[STR_LEN+1];//定义字符串数组
printf("请输入字符:\n" );
scanf("%s",str);
printf("%s\n",str);
return 0;
}
用gets输入
- 以回车换行作为终止符,可以带入空格字符串,应为空和制表符都是字符串的一部分
#include <stdio.h>
#define STR_LEN 80
int main()
{
char str[STR_LEN+1];//定义字符串数组
printf("请输入字符:\n" );
gets(str);
printf("%s\n",str);
return 0;
}
表示与存储
字符数组的定义
#define STR_LEN 80
char str[STR_LEN+1];
初始化
char str[6]={'C','h','i','n','a','\0'};//字符常量的初始化列表对数组初始化
//用字符串常量直接对数组初始化
char str[6]={"China"};//用字符串常量直接对数组初始化
char str[6]="China";//一般选择
char str[10]="China";//后面的元素会自动处理成ACSII码值为0
字符指针
- 字符指针就是字符串首地址的指针
- pstr的值可被修改,他所指向的字符串也可被修改
- 原则
- 明确字符串被保存哪里
- 字符指针指向哪里
#include <stdio.h>
int main()
{
//char *pstr[6]="China";
//将字符指针指向一个字符数组
char str[]="China";
char *pstr;
pstr = str;//地址保存,字符指针指向数组; 等价pstr = &str[0];
printf("%s\n",str);
*pstr='w';//地址指向的是首地址,等价str[0]='w'或pstr[0]='w'
printf("%s\n",str);
str[3]='D';//修改字符数组的内容
printf("%s\n",str);
return 0;
}
字符串处理函数
- 开头要加**#include<string.h>**
strlen(字符串);//计算字符串长度,实际长度
strcpy(目的字符数组,源字符串);//将源字符串复制到目的字符数组;目的字符数组要比元字符串大
strncpy(目的字符数组,源字符串,n);//将源字符串的前n个字符复制到目的字符数组;更安全
strcat(目的字符数组,源字符串);//将源字符串添加到目的字符数组
strcmp(字符串1,字符串2);
//字符串的比较是比较字符串中各对字符的ASCII码
//自左向右逐个按照ASCII码值进行比较,直到出现不同的字符或遇’\0’为止。
strncmp(字符串1,字符串2,n);
案例
#include <stdio.h>
#include<string.h>
#define N 100
int main()
{
char str[10]="China";
char str1[N];
char str2[N];
printf("%d\n",strlen(str));//输出字符串长度
strcpy(str1,str);
printf("%s",str1);
printf("\n");
strcat(str1,strcpy(str," hello"));
printf("%s\n",str1);
strcmp
}
向函数传递字符串
- 用字符数组作为函数参数
- 也可用字符指针做函数参数
- 传字符串的首地址,不是全部地址
计算实际字符个数
- const作用:保护指针变量指向的内容不被改变
- 若只向函数传数据,则把形参定义为const,防止他被意外修改
#include <stdio.h>
unsigned int MyStrlen(const char *pstr);
#define N 100
int main()
{
char ch[N];
gets(ch);
printf("%u\n",MyStrlen(ch));
}
unsigned int MyStrlen(const char *pstr)
{
unsigned int len =0;
for(;*pstr!='\0';pstr++)//pstr++:地址加1
{
len++;
}
return len;
}
函数返回字符串方法
- 数组和指针作为函数形参
- 从函数返回指向字符串的指针
- 数组不能作为函数的返回值
#include<stdio.h>
#include<string.h>
#define N 100
char *Ex(char *str);
int main()
{
char s[N];
scanf("%s",s);
printf("%s",Ex(s));
}
char *Ex(char *str)//返回字符串需要用到函数名前加*
{
static char s3[N];//static将s3变为全局变量,不加则不能返回函数内定义的字符串
int i,k;
k=strlen(str);
for(i=0;i<k;i++)
{
s3[k-1-i]=str[i];
}
return s3;//返回字符串
}