第3章C语言的基本知识
本章将对C语言的主要知识点进行复习,以期能对C语言进行更深层次的掌握。
3.1编程环境与C语言的基本数据类型
程序设计要受到硬件和操作系统等系统环境的限制的。在16位编程环境下数据类型int 一般为2个字节即16位,在32位编程环境下则为4个字节32位。同时由于字符集扩展的需要,也引入了多字节字符集和宽字节字符集。因此将char字符称为单字节字符,unicode 字符即宽字符用wchar_t定义,为16位的字符。这些都是在编程过程中应该注意的问题,否则在字符串的处理中会遇到麻烦。
在Visual C++程序设计中,可以使用通用TCHAR进行字符的定义(需要在文件的顶部添加#include<tchar.h>)。
3.2C语言的结构体(struct)
C语言使用struct来让用户定义自己的数据类型,现在其它编程语言也有相应的定义自定义数据类型的方式。如测量上常用的点,简单的说它具有点名(name)、平面坐标(x、y)和高程(z)等属性,在编程时我们可以定义为如下形式:
struct Pnt
{
char name[11];
double x,y;
float z;
};
从而将Pnt作为我们自定义的一个数据类型。如果我们要定义十个两个元素的数组,可定义为:struct Pnt pnts[10];
对结构成员元素的引用形式为:
strcpy(pnts[0].name,"A01");
pnts[0].x=100;pnts[0].y=100;pnts[0].z=100;
...................
for(int i=0;i<2;i++)
{
printf("%s:x=%lf,y=%lf,z=%lf\n",
pnts[i].name,pnts[i].x,pnts[i].y,pnts[i].z);
}
对结构类型的数据也可用指针的方式进行引用,即使用“->”进行引用结构成员。如下例所示:
struct Pnt pnt;
…………………………………
struct Pnt*pPnt=&pnt;
strcpy(pPnt->name,"A01");
pPnt->x=100;pPnt->y=100;pPnt->z=100;
3.3指针
指针是C和C++语言的重要组成部分。32位的操作系统上一个指针的大小为4个字节。
在C中,指针有很多用途,如用在函数参数中返回多个值等。例如:我们需要一个函数将一个弧度值转换成度分秒并将其分别返回。
这是一个有效的方法就是使用指针参数。
#define PI3.1415926535897932384626433832795
………………………………………………………………
double RADtoDMS(double rad,int*degree,int*minute,float*second)
{
rad=rad/PI*180;//将弧度化为度
c++strcpy函数用法*degree=(int)rad;//取度
rad=(rad-*degree)*60;
*minute=(int)rad;//取分
*second=(rad-*minute)*60;//取秒
return*degree+*minute/100.f+*second/10000.f;
}
程序调用形式为:
int main(int argc,char*argv[])
{
int d,m;
float s;
RADtoDMS(1.3254f,&d,&m,&s);//函数调用形式,
//参数d,m,s要传地址
printf("%d%d%f\n",d,m,s);
return0;
}
程序输出结果为:755623.377075
3.4函数
1.主函数:
int main(int argc,char*argv[])
其它形式的主函数:
int main()和void main()
2.函数的声明与返回类型:
严格写出函数的声明形式(返回值类型、函数名、参数类型、参数顺序和个数)和返回类型。
int add(int x,int y)
{
return x+y;
}
不能写成:add(int x,int y)形式。
3.5函数指针
如编写程序求解以下定积分:
我们采用梯形法求定积分,函数f在区间(a,b)的计算公式为:
式中:
编程思路:用函数指针变量的方法,先编写一个求定积分的通用函数(integral),再将各个积分函数以参数的形式传递给它,进行计算。
积分示例程序:
float f1(float);
float f2(float);
float f3(float);
float integral(float(*fun)(float),float,float);
int main(int argc,char*argv[])
{
printf("y1=%6.2f\n y2=%6.2f\n y3=%6.2f\n",
integral(f1,0.f,1.f),
integral(f2,0.f,2.f),
integral(f3,0.f,3.5f));
return0;
}
float f1(float x)
{
return1+x*x;
}
float f2(float x)
{
return1+x+x*x+x*x*x;
}
float f3(float x)
{
return x/(1+x*x);
}
float integral(float(*fun)(float x),float a,float b)
{
float s,h;
int i,n;
s=((*fun)(a)+(*fun)(b))/2.f;
n=100;
h=(b-a)/n;
for(i=1;i<n;i++)
{
s+=(*fun)(a+i*h);
}
return s*h;
}
运行结果为:
y1=1.33
y2=10.67
y3=1.29
3.6内存的动态分配和动态数组的实现
计算机内存有两种分配方式:在栈(stack)上和在堆(heap)上分配。一般的变量由系统自动分配在栈上,也由系统自动回收。优点是效率高,缺点是作用范围小。如果要在更大范围内使用变量,则要使用堆分配方式。
在堆上分配的内存,要由malloc函数显式分配,要由free函数显式回收。
我们看下面例子:
#include<stdio.h>
#include<malloc.h>
void fun(int n)
{
double x[n];//语法错误
int i;
for(i=0;i<n;i++)
{
x[i]=(double)i;
}
for(i=0;i<n;i++)
{
printf("x[%d]=%lf\n",i,x[i]);
}
}
int main()
{
int n;
printf("”nter value of n:”);
scanf("%d",&n)
fun(n);
return0;
}
在fun函数中,我们想根据参数值n动态的定义一个数组x[n],但这种方式在C 语言中是不允许的,在编译时会出现编译错误。
正确的fun函数实现方法为:
void fun(int n)
{
double*x;//把x声明double类型的指针
int i;
//通过malloc函数申请分配n个double类型的内存空间
x=(double*)malloc(n*sizeof(double));
for(i=0;i<n;i++)
{
x[i]=(double)i;
}
for(i=0;i<n;i++)
{
printf("x[%d]=%lf\n",i,x[i]);
}
free(x);//使用完毕后应该用free函数释放内存
}
以上示例程序说明了如何用指针实现动态数组。在这种用法中,要注意申请的内存一定要释放,否则,会造成内存泄漏。
下面我们在举一例子来说明堆上分配的内存的存在周期。
#include<stdio.h>
#include<malloc.h>
double*fun1(int n)
{
double*x;//把x声明double类型的指针
//通过malloc函数申请分配n个double类型的内存空间
x=(double*)malloc(n*sizeof(double));
return x;
}
void fun2(double x[],int n)
{
int i;
for(i=0;i<n;i++)
{
x[i]=i;
}
}
void fun3(double x[],int n)
{
int i;
for(i=0;i<n;i++)
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论