C语言复习(上) 数组,函数,字符串处理
1.序言
这是笔者的第一篇博客,笔者也刚刚结束了大一上学期的c语言期末考试,下面是我从开学到现在梳理的c语言常见算法和一些我觉得易错的点,如有错误麻烦指正,谢谢!
2.常见算法(其中一些算法笔者自己的理解写在了3.中,遇到理解不了的地方可以先去看看易错点整理)
(1)编写函数求二次方程的根
void rootx(double a, double b, double c)
{
double d = b * b – 4 * a * c;
if (d > 0.)
{d = sqrt(d);
printf("Two real roots:%f, %f\n",(-b + d) / 2. / a, (-b - d) / 2. / a);
}
else if (d == 0.)
printf("One real root: %f\n", -b / 2. / a);
else
printf("No real root\n");
}
(2)求立方根函数
double cbrt(double x)
{
double i, j;//代表y[n]与y[n+1]
if (x > -1E-6 && x < 1E-6) //x 约为0
return 0.0; /*处理特殊情况*/
i = x;
do {
j = i;
i = (2.0 * j + x / (j * j)) / 3.0;
printf("%lf\n", i);
} while (fabs((i - j) / j) >= 1E-6);
return i;
}
(3)求最大值和最小值
#define N 5
int main( )
{ int i,max,min,a[ N ];
for(i=0;i< N ;i++)
scanf(“%d”,&a[i]);
max=min= a[0];/*max,min记录最大、小值*/
for(i=1;i<N;i++)/*同时求最大值和最小值*/
{if(max<a[i]) max=a[i];
if(min>a[i]) min=a[i];
}
printf(“max=%d,min=%d\n”,max,min);
return 0;
}
(4)求最大和最小值及其下标
#define N 5
int main( )
{ int i,m,n,a[ N ];
for(i=0;i< N ;i++)
scanf(“%d”,&a[i]);
m=n=0;/* m,n记录最大值和最小值的下标 */
for(i=1;i<N;i++)/*同时求最大(小)值下标*/
{if(a[m]<a[i]) m=i;
if(a[n]>a[i]) n=i; }
printf(“max=a[%d]=%d,min=a[%d]=%d\n”
,
m,a[m],n,a[n]);
return 0; }
(5)重点:气泡法排序
#define N 4
int main( ) /* 气泡法排序,大→小*/
{int i,j,m,a[N];
for(i=0;i<N;i++)
scanf(“%d”,&a[i]);
for(j=1;j<=N-1;j++) /*N-1轮处理*/
for(i=0;i<N-j;i++)/* N-K次比较*/
if(a[i]<a[i+1])
{m=a[i];a[i]=a[i+1];
a[i+1]=m;}/* 顺序不对时交换*/
for(i=0;i<N;i++)
printf(“%5d”,a[i]);
return 0;}
(6)重点:选择排序
#define N 4
int main( ) /* 选择法排序 大→小*/
{int i,j,m,p,a[N];
for(i=0;i<N;i++)
scanf(“%d”,&a[i]);
for(j=0;j<N-1;j++)/* N-1轮处理 */
{p=j; /*p记录最大值的下标*/
for(i=j+1;i<N;i++)/*找第J轮最大值下标P*/
if(a[p]<a[i]) p=i;
if(p!=j) /* 最大值a[p]与a[j]交换 */
{m=a[p];a[p]=a[j];a[j]=m;}
}
for(i=0;i<N;i++)
printf(“%5d”,a[i]);
return 0;}
(7)在有序数列中插入数据
#define N 6
int main( )/*在有序数列(小→大)中插入数据*/
{int i,j,m,k,a[N+1];
for(i=0;i<N;i++)
scanf(“%d”,&a[i]);
printf(“input a number:\n”);
scanf(“%d”,&m);
for(k=0;k<N;k++) if(m<a[k]) break;
for(i=N;i>k;i--)
a[i]=a[i-1];
a[k]=m;
for(i=0;i<N+1;i++)
printf(“%5d”,a[i]);
return 0;
}
(8)自己写一个strcpy函数(字符串复制)
#include <stdio.h>
main ( )
{ char a[100], b[100];
int i;
printf ("Enter string 1:");
gets (b); /* 输入字符串b */
for (i=0; (a[i]=b[i])!=’\0’; i++) ;/* 复制*/
printf("Output string 2:%s\n", a);
}
(9)自己写一个strlen函数(求字符串长度)
#include <stdio.h>
main ( )
{ int length;
char line[100];
gets(line);
length=0;
while ( line[length] != ’\0’ )
length ++;
printf (”String length=%d”, length);
}
(10)自己写一个strcat函数(字符串连接函数)
#include <stdio.h>
main( )
{ char a[100],b[100];
int i, j;
printf (”Enter string 1:”);
gets (a);
printf (”Enter string 2:”);
gets (b);
for ( i=0; a[i]!=’\0’; i++ ) ; /* 确定\0位置 */
for ( j=0; (a[i]=b[j]) != ’\0’; i++, j++ ) ;
printf(”Output string 1:%s\n”
, a);
}
(11)自己写一个strcmp函数(字符串比较函数)
main( )
{ char str1[100], str2[100]; int i;
printf ("Enter string 1:"); gets(str1);
printf ("Enter string 2:"); gets(str2);
for ( i=0; (str1[i]==str2[i]) && str1[i]!=0; i++);
if ( str1[i]==str2[i] ) printf (“str1==str2\n”);
else if (str1[i]>str2[i]) printf (“str1>str2\n”);
else printf ("str1<str2\n");
(12)重点:筛选法求素数
#include <stdio.h>
enum { NUM = 200 }; //设定问题规模
int main (void) {
int an[NUM+1];
int i, j;
an[0] = an[1] = 0; /* 划去 0,1*/
for (i = 2; i <= NUM; ++i)
an[i] = 1;//初始化其余元素
for (i = 2; i * i <= NUM; ++i)
if (an[i] == 1) //跳过所有合数,找到下一个素数
for (j = i * 2; j <= NUM; j += i)
an[j] = 0; //划去当前素数的倍数
for (i = 2, j = 0; i <= NUM; ++i)//输出
if (an[i] != 0) printf("%d ",i);
putchar('\n');
return 0;
}
(13)数组元素插入函数
int InsertBefore(int arr[], int nNumber, int nPos, int nValue)
{
int i;
if (nNumber + 1 > MAXLEN)
return -1;
if (nPos < 0 || nPos > nNumber - 1)
return -2;
for (i = nNumber; i > nPos; i--) {
arr[i] = arr[i - 1]; //逐个后移
}
arr[nPos] = nValue;
return nPos;
}
(14)数组元素删除函数
int DeleteAt(int arr[], int nPos, int nNumber)
{
int i;
if (nPos < 0 || nPos >= nNumber)
return -1;
for (i = nPos; i < nNumber – 1; i++) {
arr[i] = arr[i + 1]; //逐个前移
}
return nPos;
}
(15)调用子函数,将数从大到小输出
swap(int *p1, int *p2)
{ int p;
p=*p1;
*p1=*p2;
*p2=p;
}
main()
{ int a,b;
int *pointer_1,*pointer_2;
scanf("%d,%d",&a,&b);
pointer_1=&a; pointer_2=&b;
if(a<b)swap(pointer_1,pointer_2);
printf("\n%d,%d\n",a,b);
}
思考:下面几个函数为什么实现不了交换功能?哪里出了问题?
swap(int x,int y)
{ int temp;
temp=x;
x=y;
y=temp;
}
main()
{ int a,b;
scanf("%d,%d",&a,&b);
if(a<b)
swap(a,b);
printf("\n%d,%d\n",a,b);
}
void swap(int x,int y)
{ int t;
t=x; x=y; y=t;
}
void main()
{ int a,b;
int *pointer_1,*pointer_2;
scanf("%d,%d",&a,&b);
pointer_1=&a; pointer_2=&b;
if(a<b)
swap(*pointer_1,*pointer_2);
printf("\n%d,%d\n",a,b);
}
void swap(int *p1, int *p2)
{ int *p;
p=p1; p1=p2; p2=p;
}
void main()
{ int a,b;
int *pointer_1,*pointer_2;
scanf("%d,%d",&a,&b);
pointer_1=&a; pointer_2=&b;
if(a<b)
swap(pointer_1,pointer_2);
printf("%d,%d",*pointer_1,
*pointer_2);
}
(16)将数组中的n个整数按相反顺序存放
void inv(int x[], int n)
{ int t,i,j,m=(n-1)/2;
for(i=0;i<=m;i++)
{ j=n-1-i;
t=x[i]; x[i]=x[j]; x[j]=t;
}
}
void main()
{ int i,a[10]={3,7,9,11,0,6,7,5,4,2};
inv(a,10);
printf("The array has been reverted:\n");
for(i=0;i<10;i++)
printf("%d,",a[i]);
printf("\n");
}
3.易错点(萌新)整理
1.scanf是吸收缓冲区的字符,回车也会存入缓冲区中,要注意用b=getchar()吸收回车符。不然下一个输入就会不需用户输入直接跳去判断,此时的执行情况是回车符
补充:对于缓冲区的理解:缓冲区相当于一个数据的“中转站”,printf为打印机,windows界面为用户的输入区,为了提高打印机的打印效率,用户输入的内容先存入“中转站内”,根据用户设置的条件处理数据后再传给“打印机”,剩下的部分存在缓冲区内等待处理,这样就可以形成操作流水线,一边输入一边处理数据并传给打印机,大大提高了效率。
2.注意取地址符&,使用scanf输入数字,整型数组元素时不要忘记加
3. int k=3, a[k]; /* 不能用变量说明数组 /被调函数中,可以使用变量定义 void func(int n) { int a[2n]};
4.要用到a[i+1]之类的运算时,注意数组越界问题注:冒泡排序中比完大小会交换位置,相当于比到最后剩下a[0]和a[1],所以不用担心a[i]和a[i+1]越界
5.冒泡排序:外循环进行N-1轮(i=1,i<=N-1,若i为0则注意等于号);内循环进行N-i轮(同样注意j初始值为0还是1)。无论是从大到小还是从小到大,都相当于每排完一轮后最后一个值定下,下一轮再排前面几个数,如此往复,相当于“缩进”排序(注:交换值时以temp起手,temp–a[i]–a[i+1])
6.选择排序:外循环进行N-1轮 (注:外循环j必须从0开始),p=j,内循环从j+1开始,找出最大(小)值的下标p后,交换第j轮(该轮第1个位置)和该轮最大值的值。往复,相当于将每一轮的第一个值定好,再往后推进,相当于“推进”排序。
7.有序数列中插入数:数组记得定义为N+1!用k记录需要空出的位置,k后元素后移一位(此处循环从N开始),将输入值赋给a[k]
8.注: 用scanf( )不能输入带空格、跳格的字符串
9.注:\0不要输成/0
10.字符串复制:简化的写法,把条件写到for中:(b[i]=a[i])!=’\0’
注:此处写在for内的条件是ai赋值给bi,不要写反
11.字符串连接:第一个for找’\0’的位置,第二个for也把赋值写到条件中(注:for循环,最后一次循环完,返回来不满足条件时,i的值也加了1)
12.字符串比较:第一个不同字符的ASCII码大小
13.大写转小写 strlwr 小写转大写 strupr
14.数组中把元素倒序赋值
法1中值法
无论奇偶,循环进行到i<n/2,a[i]=a[n-i-1]
法2两端缩进法
i=0,j=n-1 条件为i<j
15.求素数:i=2(0,1不是素数)
16.注:指针变量使用前一定要赋值,且定义多个指针时记得逗号后加*
17.(p++)先取p值,再使p+1;(++p)先使p+1,再取p的值
18.注:数组名不要写错
以上就是笔者一学期所得,可能指针,结构体,文件部分几乎没有涉及,待笔者放假梳理后再发下集,感谢理解!不足之处还望各位大佬指正!