————— ꧁༺ ♕ ༻꧂ —————
前言
————— ꧁༺ ♕ ༻꧂ —————
函数
递归函数
准备以后写,先留着
————— ꧁༺ ♕ ༻꧂ —————
数组
一维数组的定义
cint a[10];//注意int
1.数组大小必须是值为正的常量,不能为变量,一旦定义,不能改变大小
2.大小最好用宏定义,以适应未来的变化
#define N 10
int a[N];
一维数组的初始化
int a[5] = { 12, 34, 56, 78, 9 };
int a[5] = { 0 };//全是0.
int a[5] = { 1 };//a[0]=1,其余全是0.
int a[] = { 11, 22, 33, 44, 55 };
更高效的数组初始化方法
memset(a, 0, sizeof(a));
用sizeof(a)
来获得数组a所占的内存字节数
需要包含相应的头文件:
#include <string.h>
一维数组间的相互赋值
1.逐个元素赋值
b[0]=a[0];
b[1]=a[1];
b[2]=a[2];
b[3]=a[3];
2.通过循环语句赋值
int i;
for (i=0;i<4;i++)
{
b[i] = a[i];
}
3.更高效的数组赋值方法
memcpy(b, a, sizeof(a));//把从a开始的内存拷贝到从b开始的地址中去
需要包含相应的头文件:
#include <string.h>
二维数组的定义
二维数组 int b[2][3];
二维数组的初始化
int a[][3]={{1,2,3},{4,5},{6},{0}};
向函数传递一维数组
1.在函数声明时函数里面第一个参数是数组首地址,第二个参数是数组元素的个数。
2.在函数声明的时函数里面第一个参数必须加方括号,但是在函数调用的时函数里面第一个参数一定不要加方括号。
要背过的经典程序
1.计算最高分
注意return只能返回一个值。
int FindMax(int score[],int n)//注意加int[]
{
int max,i;
max=score[0];
for(i=1;i<n;i++)
{
if (score[i]>max)
{
max=score[i];
}
}
return max;//记得返回最大值。
}
交换法排序
直接背程序
用交换法对成绩降序排序
void DataSort(int score[], int n) /*交换法排序*/
{
int i, j, temp;
for (i=0; i<n-1; i++)//口诀:i是0到n-1,j是i+1到n。
{
for (j=i+1; j<n; j++) //口诀:i是0到n-1,j是i+1到n。
{
if (score[j] > score[i]) /*从高到低*/
{
temp = score[j];//口诀:2给空,1给2,空给1
score[j] = score[i];
score[i] = temp;
}
}
}
}
选择法排序
直接背程序
用选择法对成绩降序排序
void DataSort(int score[], long num[], int n) /*选择法*/
{
int i, j, k, temp1;
long temp2;//单独定义temp2.
for (i=0; i<n-1; i++)
{
k = i;//保存下标
for (j=i+1; j<n; j++)
{
if (score[j] > score[k])
{
k = j; /*记录最大数下标位置*/
}
}
if (k != i) /*若最大数不在下标位置i*/
{
temp1 = score[k];
score[k] = score[i];
score[i] = temp1;
temp2 = num[k];
num[k] = num[i];
num[i] = temp2;
}
}
}
顺序查找
查找不到时返回-1.
int LinSearch(long num[], long x, int n)
{
int i;
for (i=0; i<n; i++)
{
if (num[i] == x)
{
return i;
}
}
return -1;
}
折半查找
1.如果有N个数,使用折半查找最多查找log{2}{N}
2.折半查找程序如下,背过。
int BinSearch(long num[], long x, int n) // x是要查找的数字。
{
int low, high, mid;
low = 0;
high = n - 1;
while (low <= high)
{
mid = (high + low) / 2;
if (x > num[mid])
{
low = mid + 1;
}
else if (x < num[mid])
{
high = mid - 1;
}
else
{
return mid;
}
}
return -1;
}
值得注意的是:
如果用mid = (high + low) / 2;时
如果数组很大,low和high之和大于有符号整数的极限值(在limits.h中定义)
就会发生数值溢出,使mid成为一个负数
防止溢出的解决方案
修改计算中间值的方法,用减法代替加法
mid = low + (high - low) / 2;
————— ꧁༺ ♕ ༻꧂ —————
指针
变量的内存地址
1.%p表示输出变量的地址值
例如printf("a is %d,&a is %p\n",a,&a);
2.直接寻址:按变量的地址直接访问
例如scanf("%d",&a)
//把接收到的地址放入&a中。
3.间接寻址:间接寻址:通过存放变量地址的其他变量访问该变量
4.指针类型:
(1)指针变量:具有指针类型的变量,用于存放地址。
(2)变量的指针⇔变量的地址。
例子:
int *pa,*pb;
char *pc;
注意:int,char等为指针变量指向的数据类型,称为基类型。
例子:
#include <stdio.h>
int main()
{
int a=0;
int *pa=&a;//在定义指针变量pa的同时对其初始化。
printf("a is %d,&a is %p,pa is %p,&pa is %p\n",a,&a,pa,&pa);
}
5.间接寻址运算符:*
如果定义 int *pa=&a
,那么就有*pa⇔a
.
6.如果以指针作为函数的形参,则可以通过指针变量的间接引用去改变函数外实参的值。
阅读以下代码,感受通过指针变量的间接引用去改变函数外实参的值的方法。
#include <stdio.h>
void Fun(int* par);
int main()
{
int arg = 1;
printf("arg=%d\n", arg);
Fun(&arg);
printf("arg=%d\n", arg);
return 0;
}
void Fun(int* par)//注:定义了一个指针变量。
{
printf("par=%d\n", *par);
*par = 2;//将arg赋值为2.
}
指针的初始化
int *x=NULL//初始化为空指针。
指针指向变量的方式
int a=0;
int*pa;
pa=&a;
int a=0;
int*pa=&a;
编写函数实现两数的互换
int main()
{
int a, b;
a = 5;
b = 9;
Swap( &a, &b );
printf("a=%d,b=%d",a,b);
return 0;
}
void Swap( int *x, int *y )//这里定义两个指针。
{
int temp;
temp = *x;
*x = *y;
*y = temp;
}
int main()
{
int a[2] = {5, 9};
Swap(a);//函数调用数组时不要加方括号。
printf("%d,%d", a[0], a[1]);
return 0;
}
void Swap(int p[])
{
int temp;
temp = p[0];
p[0] = p[1];
p[1] = temp;
}
3.Swap函数中也可以用指针来定义,这两种方式是等价的,具体程序如下
int main()
{
int a[2] = {5, 9};
Swap(a);//函数调用数组时不要加方括号。
printf("%d,%d", a[0], a[1]);
return 0;
}
void Swap(int *p)
{
int temp;
temp = *(p+0);
p[0] = *(p+1);
*(p+1) = temp;
}
下面看几个错误例子
1.
void Swap(int *x, int *y)
{
int *pTemp;
*pTemp = *x;
*x = *y;
*y = *pTemp;
}
错误原因:指针pTemp未初始化,指针pTemp指向哪里未知,对未知单元写操作是危险的,不能借助一个未初始化的,指针变量进行两数互换。
void Swap(int *x, int *y)
{
int *pTemp;
pTemp = x;
x = y;
y = pTemp;
}
错误语言因:借助指针pTemp,交换的是地址值,不是指针指向的内容。
函数指针
1.函数指针(Function Pointer)就是指向函数的指针变量
数据类型 (*指针变量名)(形参列表);
int (*f)(int a, int b);
函数指针f指向的函数原型为:
int 函数名(int a, int b);
2.函数指针的作用:
保存地址,保存程序入口的地址,最重要的是函数指针可以指向不同函数从而表现出不同的功能
fun max;
fun=&max
举个例子
int Max(int x, int y);
int Min(int x, int y);
int Add(int x, int y);
int Max(int x, int y)
{ printf("max=");
return x>y? x : y;
}
int Min(int x, int y)
{ printf("min=");
return x<y? x : y;
}
int Add(int x, int y)
{ printf("sum=");
return x+y;
}
void Fun(int x, int y, int (*f)(int, int));
int main()
{ int a, b;
scanf("%d,%d", &a, &b);
Fun(a, b, Max);//通过指向不同的函数来实现求最大,求最小,求和的功能
Fun(a, b, Min);
Fun(a, b, Add);
return 0;
}
void Fun(int x, int y, int (*f)(int, int))
{ int result;
result = (*f)(x, y) ;
printf("%d\n", result);
}
3.功能
一般函数指针的使用
作为参数使用
举例子
1.求定积分。
求F1定积分
float F1(float x)
{
return 1 + x * x;
}
float IntegralF1(float a, float b)
{
float s, h;
int n = 100, i;
s = (F1(a) + F1(b)) / 2;
h = (b - a) / n;
for (i=1; i<n; i++)
{
s += F1(a + i * h);
}
return s * h;
}
求F2的定积分。
float F2(float x)
{
return x /(1 + x * x);
}
float IntegralF2(float a, float b)
{
float s, h;
int n = 100, i;
s = (F2(a) + F2(b)) / 2;
h = (b - a) / n;
for (i=1; i<n; i++)
{
s += F2(a + i * h);
}
return s * h;
}
用函数指针来求定积分时函数的表达式可以改变,所以就不用一个一个求了,更加方便。
float Integral(float (*f)(float), float a, float b)
{
float s, h;
int n = 100, i;
s = ((*f)(a) + (*f)(b)) / 2; //这里直接引用函数表达式,注意函数指针引用的形式。
h = (b - a) / n;
for (i=1; i<n; i++)
{
s += (*f)(a + i * h);
}
return s * h;
}
————— ꧁༺ ♕ ༻꧂ —————
字符串