自定义ASP.NET类
⒈程序集的概念
①.程序集包含至少包含以下两个要素:
程序中定义的类的元数据以及相关资源和定义这些类的IL代码;
②程序中的定义的类的程序清单(即关于程序中定义的类的信息)以及程序集本身的信息,比如程序集的版本信息等
⒉自描述特性
①程序集中包含了程序清单和程序集本身的信息
②.零安装和多版本运行
⒊成员变量的初始化:构造函数
①构造函数有两类,一类是不带参数的构造函数,一类时带有参数的构造函数。 ㈠构造函数通常与类名相同;
㈡构造函数不声明返回类型;
㈢构造函数总是public类型;
㈣在构造函数中不要做对类的实例进行初始化以外的工作。
⒋构造对象内存分配
①在堆上分配内存
②对象变量只是对象的一个引用
⒌内存回收机制
自动内存管理:公共语言运行库能够自动释放对象所占的内存空间。自动内存管理能够为对象分配内存空间,同时也能够自动释放对象的内存空间
①托管资源:对象分配的资源的回收是由垃圾回收器来管理的
②非托管资源 :.NET 框架提供 Object.Finalize 方法,它允许对象在垃圾回收器回收该对象使用的内存时适当清理其非托管资源
⒍非托管资源内存释放:析构函数
专门释放被占有的非托管资源
①析构函数没有访问修饰符,没有返回值;
②其名称和类的名称相同,但前置“~”符号;
③析构函数不能有参数
⒎类的成员变量的访问方法:属性
①属性其实就是访问类的私有字段的方法
②属性体现了对象的封装性:不直接操作类的数据内容,而是通过访问器进行访问。 ③购书项的属性
⒏数组类变量的访问方式:索引器
定义“索引器”使开发者可以创建作为“虚拟数组”的类
class IndexerTest
{
private int[] list=new int[10]; //声明字段,字段的数据类型为整型数组 public int this[int index] //声明索引访问器
{
get //get访问器
return list[index];
}
set //set访问器
{
list[index] = value;
}}}
//测试程序
class Test
{
static void TestIndex()
{
IndexerTest IndexMe = new IndexerTest();
IndexMe.[1]=5;
IndexMe[2]=10;
Response.Write(IndexMe[1]);
}
}
⒐方法重载
类中如果有两个以上的方法取的名字相同,只要使用的参数类型或者参数个数不同,编译器就知道在何种情况下应该调用那个方法,这就是方法的重载。
①构造函数可以重载
②类的方法也可以重载
⒑类的继承
①类的继承描述了类与类之间的相互关系,即继承关系。这种继承关系是面向对象编程中提高可复用性的一种方法。
②类之间的继承同样存在父和子之间的关系,即父类和子类。
子类继承父类的特性和功能,并且可以引入新的特性或者修改现有的特性,这又进一步提供了系统的可扩充性。
⒑继承语法
public partial class chap07_Default : System.Web.UI.Page
在页面继承中,继承了Page类的属性/方法/事件
①protected关键字
父类的子类可以访问而其他类是不能访问
②base关键字用于从派生类中访问基类的成员:base.printBusinessCard();
⒒方法重写(重新定义)
子类对父类的方法进行重新定义,使用new 关键字实现方法重写
⒓密封类和密封方法
①密封类是防止被其他类继承的类
㈠密封类不能被继承。将密封类用作基类是错误的
㈡在类声明中使用 sealed 修饰符可防止不慎继承此类
②对方法使用sealed修饰符可以使一个方法成为密封方法
类的多态性
⒓多态性
①多态性是指类的行为的多态性
㈠方法重载(重载后执行同样的方法产生不同的结果)(编译时多态性)
㈡虚函数:父类定义虚函数,子类重写虚函数,在生成父类对象时,具体执行的方法将根据子类的对象来定(运行时多态性)
⒔虚函数
①定义虚函数
virtual public void Draw(System.Web.UI.Page p){}
②实现虚函数
override public void Draw(System.Web.UI.Page p)
{
p.Response.Write("在ASP.NET页面上绘制圆");
}
⒕虚函数调用
①由实现类的类型来决定调用具体的函数
②虚函数实现了对象的多态性:即同一个调用执行的代码不一致
方法重载也实现了多态性
⒕类的继承方式总结
类的继承包括两种方式
①一种方式是继承实现,也就是直接继承父类的功能或者能力
②另一种继承是继承接口,也就是说父类只说明了存在某种功能或者能力并没有实现该功能和能力,而这些功能和能力的实现是通过子类来完成的,这种继承方式称为继承接口。 ⒖抽象的概念
①为什么要进行抽象
㈠抽象是由具体到一般的过程
㈡通过抽象提取一般化的部分,并且定义一般化的部分,这样可以达到代码复用的目标 ②抽象的类型
㈠将对象抽象为类。
㈡将一种类型的类抽象为抽象类。
㈢将不同的类的相同的操作抽象成接口。
⒗抽象类
在类定义中添加abstract修饰符来创建抽象基类,抽象类具有以下特性:
抽象类不能实例化
抽象类可以包含抽象方法和抽象访问器。
不能用 sealed 修饰符修改抽象类,这意味着该类不能被继承。
从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实现。
常见异常:
1、 数据不在数据词典中的异常:
产生原因:由于在创建实体类型时,没有将用到的实体序列化,导致在Config文件中找
不到所要的字段;
解决办法:在相应的实体类中开头添加[Serializable],并且在相应的实体所有的父类中也加
入[Serializable],表示已经序列化;
2、 已选择的数据有相同键的值异常:
产生原因:由于在创建实体的过程中,在实体中重复添加相同字段的数据,导致Config
配置文件在执行sql语句后选出的结果不知道想相同字段的哪个来赋值,从
而产生异常,一般多出现在[select]语句中;
解决方法: 将相应实体中的相同键的项(也就是说有相同的名称的字段)删除一个,保留一个,这
样在SQL执行过程中便可以对应赋值,不会出现这种异常现象;
3、 ViewState做添加后再次删除后的判断:
if ((ViewState["PartsReplace"] as List<实体类 >) == null || (ViewState["PartsReplace"] as
List<实体类>).Count == 0 )
{
MessageBox.Show(this.Page, MessageType.Warn, "请添加零组件信息!"); return;
}
4、 Config文件中的模糊查询的语句:like % || 某个字段 ||%;
5、 Repeater或者gridview中显示日期格式的代码: 只需要加上:
<%#Convert.ToDateTime(DataBinder.Eval(Container.DataItem,"PostTime")).ToShortDateString()%>
就可以达到效果了!
简化:<%#Convert.ToDateTime(Eval("intime")).ToShortDateString()%>
<%#Eval("PubDate","{0:yyyy-MM-dd}")%>
另外一中显示方式:#Eval("PubDate","{0:d }")%>
一、C示例讲解
1、将100~200之间的素数打印出来
① N-S图 2.16 P7 程序P10 (6)(C程序设计题解….)
② 求素数N逻辑方法是:先定义i且i<=sqrN; N/i ,只有不能整除时循环,直到i=sqrN时,如仍不能整除见分则N是素数
2、求两个数m和n的最大公约数
①N-S图 2.17 P8 程序P10 (7) (C程序设计题解….)
②求公约数的方法(m>n):m/n付给r,即r<=m/n,然后再付值:m=n n=r
③ r=m/n m=n n=r循环下去
判断润年实例及N-S图
① N-S图分析见P11(C程序设计题解….)例见课本P100
总结:N-S图是逻辑分析程序的走路,然后才可写出程序,试用VB来分析上三例的设计 C程序实例可见书本(C程序设计题解与上机指导 第二版)
二、特殊字符的表现见课本P48
例main()
{
Printf(“_ab_c\t_de\rf\tg\n”); _表示空格 屏上结果:fab-c---gde h------jik
Printf(“h\ti\b\bj_ _k”); 打印结果:f-------gde h------j-k
}
说明:1、出-ab-c,遇到t后到第九列输出-de,后遇到r返回到第一列输出f,遇到t即在本例九列输出g,具体在课本P49例3.5; 2、单引号里表示字符,双引号表示字符串;3、运算的优先级见课本P375;例题见(C程序设计题解与上机指导 第二版)P15例3.9及P17
三、小知识点
①于++i与i++
如:dim i=8,j=10; =++i,n=j++; printf(“%d,%d”,m,n);例见(C程序设计题解P15例3.10
说明:++i:i的值先变成9,然后将9付给m即m=9,i=9;j++先将j的值付给n即n=10,然后
j的值再加1,即j=11
② 整型变量(单精度占两个字节,16位)输出以%d,定义是int形式;实型(浮点占4个字符,32位)输出%f,定义float表示;字符(占1个字节,8位)输出%c,定义char表示(各见课本P43,P45,字符串以%s输出,以str形式输入
③ 小数,正负的取整,取模的运算:如int(-1.7),int(1.7),3.7%2,1.3%2等,在c中多数情况下(c的课本P55)取整取向零靠近;VB中取模取整的表示符是:/ \ 及其运算方法?
四、C语言的运结构
1、顺序结构示例讲解
Main()
{
Int a,b,c;
Long int u,n;
Float x,y,z;
Char c1,c2;
A=3,b=4,c=5;
X=1.2,y=2.4,c=3.6;
U=5127,n=12876;
1
C1=’a’,c2=’b’;
Printf(“\n”);
Printf(“a=%2d,b=%2d,c=%2d\n”,a,b,c); 黑体表示输出的列
Printf(“x=%8.6f,y=%8.6f,z=%9.6f\n”,x,y,z); 黑体表示输出列及小数位数
Printf(“x+y=%5.2f,y+w=%5.2f,z+x=%5.2f\n”,x+y,y+z,z+x);
Printf(“u=%61d,n=%91d\n”,u,n);
Printf(“c1=%c or %d(ASCII)\n”,c1,c2);
}
字符数据的输出
①%m.ns;输出占m列,但只取字符串中左端n个字符,这n个字符输出在m列的右侧,左补空格;%-m.ns, 其中m n含义同上,n个字符输出,在m列范围的左侧,右侧补空格,如果n>m,则m自动取n值,保证n个实际字符正常输出
②%m.nf,指定输出的数据共占m列,其中有n位小数,如果数值长度小于m,则左端补空格 %-m.nf,指定输出的数据共占m列,其中有n位小数,如果数值长度小于m,则右端补空格 格式的输入与输出
Scanf(“格式控制,地址列表”),printf(“格式控制,输出列表”)
说明:①格式控制由%和格式字符组成,如%d,%f;地址列表由&+字符名组成;scanf(“%d”,&a) ②输出列表是需要输出的一些数据,如%d;输出列表由字符名组成;printf(“%d”,a) Putcher只能输出字符,而且只能是一个字符,而printf可以输出多个数据,且为任意类型
④ 输入数据不能规定长精度,如可scanf(“%7.2f”,&a);想使a值为12345.67是不 合法的,只有输出才可规定精度如printf(“%7.2f”,a);输入时要与输出时格式相对应:scanf(“%d:%d”,&a,&b),在銉盘上输入12:13
VB里的输入与输出格式要求,各运算符的表示与计算,各种数据的表示,如:字符,实数等
2、选择结构程序设计
内嵌套 ①if(?) ②if? ③switch()
If(?) else if? case1:?
Else? else if? case2:?
Else? else if? case3:? 注:C中没有end if ①②格式的应用实例
例1有3个整数a b c由键盘输入,输出其最大的数的方法,画出N-S图(见设计解题P25) Main()
{
Int a,b,c;
Printf(“请输入三个整数”);
Scanf(“%d,%d,%d”&a,&b,&c);
If (a<b)
If(b<c)
Printf(“max=%d\n”,c); 只有一个“;”号,表示这所有的是一句,if内嵌套 Else
Printf(“max=%d\n”,c); 另一句
Else if(a<b)
Printf(“max=%d\n”c); 另一句
Else
2
Printf(“max=%d\n”,a); 另一句
}
例2、 x (x<1)
y= 2x-1 (1<=x<10)
3x-11 (x>=10)
Main()
{
Int x,y;
Scanf(“%d”,&x);
If (x<1)
{
y=x;
printf(“x=%3d,y=x=%d\n”,x,y); “x=”, “y=x=”是输出字符,这是一句 }
Else if(x<11)
{
Y=2*x-1;
Printf(“x=%3d,y=2x-1=%d\n”,x,y);
} 另一句 因为每个条件句有两条语句所以 Else 要用{},同条件句一起作为一句语句
{
Y=3*x-11;
Printf(“x=%3d,y=3*x-11=%d\n”,x,y);
} 另一句
}
#如果if 与else的数目不一样,为实现程序设计的企图,可以加花括号来确定配对关系 如 if ( )
{if ( )语句1} 这时的else与第一个if配对,如果没有花括号,则与第二个 Else 语句2 if 配对
③ switch 语句的应用
main()
{
Int c,s;
Float p,w,d,f;
Scanf(“%f,%f,%d”,&p,&w,&s);
If (s>=300)
C=12;
Else if c=s/250;
Switch(c) c是switch的表达式
{
Case 0:d=0;break; 0, 1等是switch的常量表达式
Case 1:d=2;break;
…………..
Case 12:d=15;break; switch的表达式要与case后面的常量表达式的数据
3
} 类型及值是一样的
F=p*w*s*(1-d/100.0);
Printf(“weight=%15.4f”,f);
} #找出VB的选择结构框架及示例
3、循环结构
一、循环的控制 goto语句
1、 goto 语句及goto语句构成的循环
goto语句为无条件转向语句,格式为 goto 语句标号;语句标号由字母、数字和下划线组成,其第一个字符必须为字母或下划线;如goto 123(错),goto label_1(对)
2、 作用:与if语句一起构成循环
例:求1+2+3+-----+100的和
Main()
{
Int I,sum=0;
I=1;
Loop:if (i<=100)
{
Sum=sum+I;
I++;
Goto loop;
}
Printf(“%d’,sum);
}
二、循环的控制 while语句
结构(表达式)语句
当表达式为非0时,执行while语句中的内嵌套语句,表达式只能为关系表达式、逻辑表 达式,当表达式为常量表达式时,就进入死循环
例:求1+2+3+-----+100的和
Main() main()
{ { int sum=0,I;
Int I,sum=0; scanf(“%d”,&i);
I=1; while (i<=10)
While (i<=100) {sum=sum+i
{
Sum=sum+I; i++ }
I++;
} printf(“sum=%d”,sum);
Printf(“%d”,sum); }
}
三、循环的控制 do--while语句
格式 do / 循环语句 / while (表达式)
特点:先执行一次指定的循环语句,然后判断是否符合要求去执行循环
例:求1+2+3+-----+100的和
Main( ) main ()
4
{ {int sum=0,I ; scanf(“%d”,&i);
Int I,sum=0; do { sum=sum+I; i++; }
I=1; while (i<=10); printf(“sum=%d”,sum);
Do
{ }
Sum=sum+I; while 与do---while循环的比较:一般情况下,当处理同一问题时,
I++; 并循环体部分是一样的,则结果相同,但如while后面的表达式
} 一开始为假(0值)时,两种循环的结果是不同的,如上右边两 While (i<=100); 例中输入1 则两结果都是sum=55;如输入11,则while循环结果 Printf(“%d”,sum); 是sum=0,而do---while循环结果是sum=11
}
四、for循环语句
①表达式形式:for (表达式1;表达式2;表达式3;) 它的执行过程:a、先求解表达式1;b、求解表达式2,若其值为真,则执行for语句指定的内嵌套语句,然后执行下面的语句,若为假,则结束循环语句;c、求解表达式3,求解完后再回头(循环)去执行求解表达式2…. 例剖析 相当 i=1;
For (i=1;i<=100;i++) while (i<=100)
Sum=sum+I; { sum=sum+I;i++;}
一般情况下,for 语句可以改写成while语句;即:表达式1;while (表达式2) {语句;表达式3} ②for 循环的表达式1、3可省,具体省略后的形式变化见课本P111-112
五、循环的嵌套
While() do for (;;;)
{?? {?? {for (;;;)
While() do
{ {?? {
?? } 执行语句;
} while(); }
} while(); }
} 执行语句;???
几种循环的比较见课本P114
Break语句和continue语句
Break语句用来从循环体中跳出 循环体提前结束循环,接着执行下面的语句,但它不能用于循环语句和switch语句之外的任何其它语句
Continue语句用来结束本次循环,不是终止整个循环体
Continue的应用例子
Main()
{
Int n;
For (n=100;n<=200;n++)
{
If (n%3==0) 当n能被3整除时执行continue语句,结束本次循环(即跳过 Continue; printf函数语句)只有当n不能被3整除时才能执行printf Printf(“%d”,n); 函数
5
}
}
For 内嵌套实例
打印出以下图案
* main()
*** {int I,j,k;
***** for (i=0;i<=3;i++) i控制输出行(上面的4行)
******* {for (j=0;j<=2-I;j++) 此for{}号可省,因与前for没有;号,是同一句 ***** printf(“ ”); 输出*号前面的空格
*** for (k=0;k<=2*I;k++) 输出*号
* printf(“*”); 输出完一行*号后换行
printf(“\n”); }
for (i=0;i<=2;i++) 输出下面的3行*号
{for (j=0;j<=I;j++) 此for{}号可省,因与前for没有;号,是同一句 Printf(“ “); 输出*号前面的空格
For (k=0;k<=4-2*I;k++)
Printf(“*”); 输出*号
Printf(“\n”); 输出完一行*号后换行“
}
}
## for (.…) for (.…) 效果等同情况:因为第二个for没有并行语句, for (.…) { for (.…) 因为第三个for都属于第二个for循环的执行 for (.…) for (.…)} 语句,如果第二for有平行语句就不同了
例:main( ) 结果为: * 如去掉第二个for后 {int I,j,k; *** 的{};结果为: For(i=0;i<=3;i++) *****
{for(j=0;j<=2-I;j++) ******* *********
Printf(“ ”);
For(k=;k<=2*I;k++) 可见两种情 况结果不同,原因在于第二个 Printf(“*”); for后第二for有平行语句Printf(“ ”)
Printf(“\n”);} 第三个for不属于第二个for循环的执行 }
例:main( )
{int I,j,k; 结果: 去掉第二个for的{}结果是: For(i=0;j<=3;i++) *
{for(k=0;k<=2*I;k++) ***
Printf(“*”); ***** ****************
Printf(“\n”); } *******
}
例:main( )
{int a,b; 程序运行结果:
6
For(a=1;a<=3;a++) 1*1=11*2=21*3=31*4=4
{for(b=1;b<=4;b++) 2*1=22*2=42*3=62*4=8
Printf(%d*%d=%d,a,b,a*b); 3*1=33*2=63*3=93*4=12
Printf(“\n”);} 去掉第二个for运行结果是
} 1*1=11*2=21*3=31*4=42*3=62*4=83*1=31*2=63*3=93*4=12
例:main( ) main( )
{ Int a,b; { Int a,b;
For(a=1;a<=3;a++) For(a=1;a<=3;a++)
{for(b=1;b<=4;b++) for(b=1;b<=4;b++)
Printf(%d*%d=%d,a,b,a*b);} Printf(%d*%d=%d,a,b,a*b);
} }
运行结果一样是:1*1=11*2=21*3=31*4=42*3=62*4=83*1=31*2=63*3=93*4=12
3、 一维数组元素
一、小知识点
① 数组里的元素下标是从零开始的,常量表达式中可以包含常量和符号常量,不能是变量 ② 可以只给一部分元素付值,如:int [10]={1,2,3,4,5},而这只是给数组前五个元素付值 ③ 如果想使一个数组中的全部元素付值为0,可以写:int [10]={0,0,0,0,0,0,0,0,0,0}
或写成a[10]={0}
④ 在对全部数组元素付初值时可以不指定数组长度如:a[]={1,2,3,4,5},在定义数组后,
如:a[10]={1,2,3,4,5,6,7,8,9},从键盘上获取元素时可用scanf(“%d”,&a[i]),但不能写成scanf(“%d”,&a)或scanf(“%d”,&a[])或scanf(“%d”,a)
4、 二维数组元素
① 格式:类型说明符 数组名[常量表达式][常量表达式]
如:float [3][4],float [5][10]定义a为3*4(3行4列),b为5*10(5行10列)的数
组
A[0][0],A[0][1],A[0][2],A[0][3]
A[3][4]= A[1][0],A[1][1],A[1][2],A[1][3]
A[2][0],A[2][1],A[2][2],A[2][3]
②二维数组的付值:I、分行付值:int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}} 等同于int[3][4]={1,2,3,4,5,6,7,8,9,10,11,12} 1,0,0,0 其值是对
II、 可以对部分付值:int [3][4]={{1},{5},{9}}等同于a[3][4]= 5,0,0,0 各行中的 9,0,0,0 第一个元素
Int a[3][4]={{1},{5,6}},对第三行不付值,Int a[3][4]={{1},{},{5,6}}第二行不付值 III、对数组全部付值时可以省略行数的下标如:a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}效果等同于a [][4]= {1,2,3,4,5,6,7,8,9,10,11,12}
IV、可以只对部分元素付值,而省略第一维的长度(行的下标),但应分行付值,如: Int a [][4]={{0,0,3},{},{0,10},}效果等同第一行0,0,3,0第二行0,0,0,0第四行0,10,0,0
二维数组应应用用举例:1 2 3 1 4
将a=4 5 6 的行与列互换成b= 2 5
3 6
程序: main( )
{ int a[2][3]={{1,2,3},{4,5,6}};
Int b[3][2],ij;
7
Printf(“array a:\n”);
For (i=0;i<=1;i++)
{for (j=0;j<=2;j++)
{printf(“%5d”,a[i][j]);
B[j][i]=a[i][j]]; } a[i][j]中的i与倒数第二行b[i][j]中的i不一定一样
Printf(“\n”);}式 因为i是变量,其值是可变的,故i在程序中是不 Printf(“array b:\n”); 确定的
For (i=0;i<=2;i++)
{for (j=0;j<=1;j++)
Printf(“%5d”,b[i][j]);
Printf(“\n”);}
}
N-S图 for i<=1 前程序的N-S图 for i<=2 后段程序的N-S图 For j<=2 for i<=1
输出a[i][j] 输出b[i][j]
并a[j][i]=a[i][j]
5、 字符数组
① 字符数组的定义:基本与前面的整型数组定义相同,不同之处:如果初值个数小于数
组长度,只将这些字符付给数组中的前面那些元素,其余的元素定义为空字符。
② 字符数组引用实例
输出一个钻石图形
程序: main( )
{char
diamond[][5]={{“’ ’,’ ’,’*’”},{“’ ’,’*’,’ ’,’*’”}{“’*’,’ ’,’ ’,’ ’,’*’”},{“’ ’,’*’,’ ’,’*’”,},{“’ ’,’ ’,’ *’”}}
Int I,j; 输出结果 *
For (i=0;i<5;i++) * *
{for (j=0;j<5;j++) * *
Printf(“%c”,diamond[i][j]); * *
Printf(“\n”); } *
}
##上程序第二个for是嵌套于第一个for里的;①如果一个字符串第10个字符为’\0’,则此
字符串的有效长度为9,也就是说在遇到字符’\0’时,表示字符串结束,由它前面的
字符组成字符串;②系统对字符串常量也会自动加一个’\0’作为结束符,所以会比实
际多一个字符;③所以有了结束标志’\0’后,字符数组的长度就显得不那么重要了,
只要数组长度大于字符串的实际长度就可④所以字符数组表示字符串时,可以如此定
义:char []={“china”};⑤它的输出与数组不同,要:printf(“%c”,a[i]),因为它输
出的是字符数组名,不是数组元素,字符串的输出printf(“%s”,a);⑥字符数组的
输入:scanf(“%s”a),或scanf(“%c”a)它不用scanf(“%s”%a[i]),原因是scanf
函数中的输入项是字符数组名,它应该在先前就已被定义,如:scanf(“%d”,&str)
是错误的,因scanf函数中的输入项是字符数组名时不用再加地址标识符&,因为在
C语言中数组名代表该数组的起始地址
如: C 2000 此数组若其名是C,占6个字节,程序中如果只写数组名C, H 2001 ,它就代表起始地址为2000,然后它会按第一个地址逐个输 8
I 2002 入或输出。
N 2003
A 2004
\0 2005 字符串处理函数祥情见课本P135-138
6、 函 数
一、小知识点
① 函数说明:一个C程序---包含多个源程序;一个源程序----包含多个函数;(也可
说一个程序包含多个函数)
② C程序的执行从main函数开始,即主函数,调用其它函数后,流程返回到main
函数,在main函数中结束整个程序的运行,注意main函数是系统定义的
③ 函数间平等,可互相调用,但不能调用主函数(C中main函数)
二、 函数种类
① 从使用者角度看可分两种:标准函数即库函数与用户自己定义的函数
② 函数的形式看:无参函数与有参函数
三、 无参函数定义的一般形式 无参函数
类型标识符 函数名() 例 main( ) printfstar( )
{ {printfstar(); {printf(“********”);}
声明部分 printf_message(); print_message( )
语句 printfstar(); {printf(“how do you \ndo!”); } } }
说明:无参函数一般不需要返回值,因此可以不写类型标识符
四、有参函数定义的一般形式 例 有参函数
类型标识符 函数名(形式参数列表)main( ) max(intx,int y) { { int a,b,c; {int z;
声明部分; scanf(“%d,%d”,&a,&b); z=x>y?x:y; 语句; c=max(a,b); a,b是实参 return (z) } printf(“max is %d”,c); } }
# 类型特别说明
① 上例中没有函数定义,即int max(int x,int y)前的int,原因在于C语言规定凡
不加类型说明的函数,一律自动按整型处理
② 定义函数时对函数值说明的类型一般应该和return语句中的表达式类型一致,如
上例中的变量Z为整型,即max函数也为整型函数,此max函数隐含定义为整型,
但如不同,则以函数类型为准,可以对数值数据自动进行类型转换
③ 要求函数返回值的要用到语句return(),如上例中的return()也可这么写:return
z=return(z)=return(x>y?x:y)
④ 自我认为:上例中被调用函数x,y形参的类型与主函数a,b函数实参类型相同,与
这量c可同可不同, c变量与被调函数max类型可同可不同,c变量类型只是限定
输出函数的格式,即输出函数的类型;#类型如不同则按付值进行转换,如下例中
的a实参为3.5,而形参x为整型,则将3.5 转换成整型然后送到形参b,但此时应
将函数max放在main函数前面或在main函数中对max函数作原型声明,如下:
Main( ) int max(int x,int y) int可省
{int max(int x,inty); int可省 { int z;
Float a,b; z=x>y? x:y;
Int c; return(z);
9
C=max(a,b); }
Printf(“max is %d”,c)
}(后接max函数)
7、 形参与实参说明
形参:调用前不占用内存,调用时分配内存并获得值,高用结束后释放内存空间
实参:可以是常量、变量、表达式,要求它们有确定的值
参数的传递:只由实参传给形参,函数值再由被调函数返回值给主调函数,而不能由形参传给实参,因被调函数一旦结束后,形参单元被释放。
返回值图: c=max(a,b); 主函数
--------------------------------
Max(int x,int y); max函数
{int z;
Z=x>y? x:y;
return (z); } z返回到c=max(a,b)中,得到最大值付给c 补充:关于do---while循环语句:执行do与while之间的循环,当条件不符合while要求时,就结束循环再执行while后面的语句,例见课本P157
8、 指 针
①概念:如果在程序中定义了一个变量,在编译时,就给这个变量分配了内存单元,如:
在C系统中整型变量、实型变量、字符型变量的内存单元的长度空间分加别是2、
4、1个字节,而内存单元(内存区)第一个字节有一个编号,这就是地址
②量的存储、这义与输出
I、 一程序定义三整型变量I,j,k,编译时系统分配2000和2001两个字节空间给i,2002\2003
两字节给j,2004、2005字节空间给k
II、存储变量:在程序中一般是通过变量名来对内存单元进行存取操作的,其实程序给它
编译以后,已经将变量名转为变量地址,对变量值的存取就是通过地址进行的,如:scanf(“%d”,&i)在执行时就是从键盘上输入的值送到地址为2000开始的整型存储单元中,所以i前要有&符号来获取i变量的存储单元空间地址
III、输出变量:printf(“%d”,i)等形式;根据变量名与地址之间(这对应关系是在编译时就
确定了的)找到变量i的地址2000,然后由2000开始的两个字节中取出数据给变量i
9、 量、指针、指针变量
指针变量:存储变量地址的一种特殊变量;如i_pointer=&i;i_pointer就是指针变量,它存储
的是变量i的地址,如i的地址就是2000,2001两个字节长度的存储空间,则指
针变量i_pointer的值就是2000即变量i所占用的单元的起始地址
指针:一个变量的地址称为该变量的指针,如2000是变量i的指针;指针变量i的值(即
指针变量存放的值是)是指针(地址)
#可说变量i的指针是2000,如有i_pointer=&i为前提的话,指针变量i_pointer的值是2000;简单说明:如果一个变量放加一变量的地址(即指针),则它称为“指针变量”
10、变量的指针和指针变量及指向变量的指针变量
变量的指针:就是变量的地址,也就是该变量的指针
指针变量:存放变量地址的变量,或存放变量指针的变量
指向变量的指针变量(简称指针变量?):引入*i-pointer,即在指针变量前加上“*“符号表
示指针变量i_pointer所指向的变量;*i_pointer等同于该变量a,也可写
i_pointer=&a=&*i_pointer
定义指针变量形式:基类型 *指针变量名
10
如:float *pointer_1 说明:“*“符号表示该变量的类型为指针变量,pointer_1是指针变量名,float是指针变量的基类型,即实型,注意:一个指针变量只能指向同一个类型的变量,因为不同类型的变量占的字节不同,如float*pointer_1移动一个位置(即指针移动一个位置)意味移动4个字符,int *p ointer_2意味移动两个字节。故必须指向同一个类型 例pointer_1=100(错);pointer=&a(对) ;pointer_1=a(错);*pointer_1=&a(错)
“*”为指针运算符,如:*p为指针p指向的存储单元 pointer/&a----a/*pointer 例:main()
{int a,b;
Int *pointer_1,*pointer_2; 表示定义两个指针变量*pointer_1,*pointer_2;
A=100,b=10;
Pointer_1=&a;
Pointer_2=&b;
Printf(“%d,%d\n”a,b);
Printf(“%d,%d\n”*pointer_1,*pointer_2); }表示pointer_1,pointer_2指针所指向的变量 *&a等同于*pointer_1; *&a表示:先进行&a运算,得到a的地址,即指针变量,再进行*运算,即该地址(指针)所指向的变量。
两指针变量运用的实例
例1、main( ) 例2、swap(int *p1*p2)
{int *p1,*p2,a,b; {int temp;
Scanf(“%d,%d”,&a,&b);
P1=&a,p2=&b;
If (a<b)
{p=p1;p1=p2;p2=p;}
Printf(“\na=%d,b=%d”,a,b);
Printf(“max=%d,min=%d”,*p1,*p2);
}
运行结果5,9----a=5,b=9----max=9,min=5
11
一C示例讲解1将100200之间的素数打印出来NS图216P7程序P106C程序设计题解求素数N逻辑方法是先定义i且iltsqrN…
C语言最重要的知识点总体上必须清楚的1程序结构是三种顺序结构选择结构分支结构循环结构2读程序都要从main入口然后从最上面顺序往下…
C学习小结分类CC20xx060315571193人阅读评论2收藏举报cdeletestruct编译器classnull一构造和析…
C知识总结多态重载重写函数指针函数对象虚函数等动态连接库的创建步骤一创建NonMFCDLL动态链接库1打开FilegtNewgtP…
C总结1define宏定义的作用范围仅限于当前文件即file1c中定义definePI314在file2c中该宏定义不起作用通过将…
这一周的C语言实训就要结束了,这一周我们实训的课题是蛇行数组,就是使一个n*n的二维数组按按蛇行走的样子一样从左上角排列到右下角,…
金屯镇中心小学开展校园环境卫生整治活动总结为进一步加强学校环境综合治理工作,推动创建文明校园活动的深入开展,维护学校及周边环境秩序…