1.数组基础
(1)数组定义
<类型>变量名称[元素数量(必须为整数)];
int x;
double sum=0;
int cnt =0;
int number[100];//定义一个数组
scanf("%d",&x);
while(x!=-1){
number[cnt]=x;//对数组元素赋值
sum += x;
cnt++;
scanf("%d",&x);
}
if(cnt >0){
int i;
double average=sum/cnt;
for(i=0; i<cnt;i++){//遍历整个数组
if(number[i]>average){
printf("%d ",number[i]);
}
}
}
(2)容器
数组可以看做是一种容器,放东西的地方;特点是:
a.其中所有的元素具有相同的数据类型;
b.一旦创建无法改变大小;
c.数组中的元素在内存中是连续排列的
(3)数组单元
使用数组时放在[ ]中的数字叫做下标或索引,其从0开始计数;所以有效的下标范围是[0,数组的大小 - 1]
注意防止下标越界,出现segmentation fault
(4)下标使用变量[C99]
int x;
double sum=0;
int cnt =0;
printf("请输入数字的数量:");
scanf("%d",&cnt);
if(cnt > 0){
int number[cnt];//定义一个数组
scanf("%d",&x);
while(x!=-1){
number[cnt]=x;//对数组元素赋值
sum += x;
cnt++;
scanf("%d",&x);
}
}
(5)散列计算
写一个程序,输入数量不确定的[0,9]范围内的整数,统计每一种数字出现的次数
const int NUM=10;
int x;
int count[NUM];
for(int i=0;i<NUM;i++){//数组的初始化
count[i]=0;
}
scanf("%d",&x);//输入
while(x!=-1){
if(x>=0 && x<=9){
count[x]++;
}
scanf("%d",&x);
}
for(int i=0;i<NUM;i++){//遍历数组
printf("%d出现的次数为%d\n",i,count[i]);
}
2.二维数组
(1)二维数组的形式
int b[][4]={{2,3,4,5},{1,2,3,4}};//行数可以省略
int a[3][5];//3行5列的矩阵
for(int i=0;i<3;i++){//遍历二维数组
for(int j=0;j<5;j++){
a[i][j]=i*j;
}
}
(2)tic-tac-toe(井字棋)游戏
const int size =3;
int board[size][size];
int i,j,numOfX,numOfO;
int result = -1; //-1:没人赢 1:X赢 0:O赢
for(i=0;i<size;i++){//读入数据
for(j=0;j<size;j++){
scanf("%d",&board[i][j]);
}
}
//检查行
for(i=0;i<size && result==-1;i++){
numOfO=numOfX=0;
for(j=0;j<size;j++){
if(board[i][j] == 1){
numOfX++;
}else{
numOfO++;
}
}
if(numOfO==size){
result=0;
}else if(numOfX==size){
result=1;
}
}
//检查列
if(result==-1){
for(j=0;j<size && result==-1;j++){
numOfO=numOfX=0;
for(i=0;i<size;i++){
if(board[i][j] == 1){
numOfX++;
}else{
numOfO++;
}
}
if(numOfO==size){
result=0;
}else if(numOfX==size){
result=1;
}
}
}
//检查正对角线
if(result==-1){
numOfO=numOfX=0;
for(i=0;i<size;i++){
if(board[i][i] == 1){
numOfX++;
}else{
numOfO++;
}
}
if(numOfO==size){
result=0;
}else if(numOfX==size){
result=1;
}
}
//检查负对角线
if(result==-1){
numOfO=numOfX=0;
for(i=0;i<size;i++){
if(board[i][size-i-1] == 1){
numOfX++;
}else{
numOfO++;
}
}
if(numOfO==size){
result=0;
}else if(numOfX==size){
result=1;
}
}
3.数组运算
(1)数组初始化
int a[]={3,4,5,67,8,23,354,46,46,57,67};//数组的集成初始化
{
for(int i;i<sizeof(a)/sizeof(a[0]);i++){
printf("%d ",a[i]);
}
}
(2)应用
<1>线性搜索
int search(int key, int a[],int length){
//数组作为参数时,无法利用sizeof来计算数组大小,也无法在[]直接给出数字
int ret=-1;
for(int i=0;i<length;i++){
if(a[i] == key){
ret = i+1;
break;
}
}
return ret;
}
int main()
{
int a[]={3,4,5,67,8,23,354,46,46,57,67};//数组的集成初始化
int x,loc;
printf("请输入一个数字:");
scanf("%d",&x);
loc=search(x,a,sizeof(a)/sizeof(a[0]));
if(loc !=-1){
printf("%d在第%d个位置上\n",x,loc);
}else{
printf("%d不存在\n",x);
}
return 0;
}
<2>二分搜索
基于已经排序的情况一个效率较高的搜索方案
l
o
g
2
N
log_2N
log2N
int search(int key, int a[], int len){//二分搜索
int ret=-1;
int left=0;
int right=len-1;
while(right > left){
int mid=(left+right)/2;
if(a[mid]==k){
ret = mid;
break;
}else if(a[mid]>k){
right=mid-1;
}else{
left=mid+1;
}
}
return ret;
}
<3>素数进阶
#define NUM 10
//求前10个素数
int isPrime(int x,int knownPrimes[],int numberOfKnownPrimes){
int ret =1;
for(int i=0;i<numberOfKnownPrimes; i++){
if( x% knownPrimes[i]==0 ){
ret =0;
break;
}
}
return ret;
}
int main()
{
int prime[NUM]={2};
int count = 1;
int i=3;
while(count < NUM){
if(isPrime(i,prime,count)){
prime[count++] = i;
}
i++;
}
for(i=0;i<NUM;i++){
printf("%d",prime[i]);
if((i+1)%5) printf("\t");
else printf("\n");
}
return 0;
}
<4>选择排序
int max(int a[], int len){
int maxid=0;
for(int i=1;i<len;i++){
if(a[i]>a[maxid]){
maxid=i;
}
}
return maxid;
}
int main()
{
int a[]={23,34,24,35,46,72,14};
int len=sizeof(a)/sizeof(a[0]);
//选择排序--每次寻找最大的那个数,再去与最后一个交换顺序
for(int i=len-1;i>0;i--){
int maxid=max(a,i+1);
//swap a[maxid]<==>a[len-1]
int t=a[maxid];
a[maxid]=a[i];
a[i]=t;
}
for(int i=0;i<len;i++){
printf("%d ",a[i]);
}
return 0;
}
4.函数基础
(1)函数定义
类似于数学中的y=f(x)
void sum(int begin, int end){//函数头=返回类型+函数名+参数表
//函数体start---
int sum=0;
for(int i=begin;i<=end;i++){
sum +=i;
}
printf("从%d到%d的和为%d\n",begin,end,sum);
//---end
}
//main中调用函数示例
sum(10,11);
(2)函数声明
void sum(int begin, int end );//放在main函数之前,函数定义可放在main后
(3)参数传递与局部变量
C语言传统上最大的漏洞:调用函数时给的值与参数的类型不匹配
#include <stdio.h>
//这是一个值得商榷的代码,它能够交换a、b的值吗?我们来分析一下
void swap(int x,int y){//参数
int t=x;//此时的t、x、y皆为局部变量(自动变量、本地变量)
x=y;
y=t;
}//注意:局部变量的生存期在块内,即到此为止t、x、y全部消亡了!!!
int main()
{
int a=4;//值
int b=6;
swap(a,b);
printf("a=%d b=%d\n",a,b);//此代码输出结果为a=4 b=6
return 0;
}