c 语言笔记-专接本大纲中考核点
一、c 语言程序的结构
1. 理解 C 程序的基本结构及执行过程
编辑,预处理,编译,链接,执行
执行过程.
2. 理解 C 程序中头文件、注释等概念,会在程序中正确使用文件包含命令以及添加注释
头文件就是把""或者<>里面的文件展开在此处
常用头文件:
stdio.h 标准输入输出
stdlib.h 标准常用库
string.h 字符串函数库
math.h 数学库
ctype.h 字符函数库
time.h 时间库
windows.h 微软视窗库
单行注释: // 后面写注释
多行注释: /* 里面写注释 */
3. 理解 C 函数的构成形式.
c 语言程序至少有一个 main() 且只能有一个(函数是 c 语言最小单位)
函数由两部份组成:函数头void max( )
和函数体{ } // 花括号内的称为函数体
#include<stdio.h>
int main()
{
printf("first c program");
// 最简单的c程序
}
4. 了解 C 程序源代码的书写格式
二、数据类型及其运算
1. 掌握 C 语言的基本数据类型,了解不同数据类型常量的表示方法.
字符型:描述单个字符 char
整型:描述整数,整数在计算机上是准确表示的 int
浮点型、双精度型:描述实数,实数在计算机上一般是近似表示的,浮点型的近似程度比较低,而双精度型的近似程度比较高 float 、double
无值类型:没有具体的值,通常用来描述无形式参数或无返回值的 C 函数,以及无定向指针
逻辑型:描述逻辑真(其值为 1)与逻辑假(其值为 0)
复数型:描述复数(_complex)和纯虚数(_imaginary)使用逻辑型时必须包含头文件 stdbool.h,使用复数型时必须包含头文件 complex.h
2. 掌握变量的定义、初始化和引用的基本方法.
char a='a';
int a=1;
float a=1.11;
doublue a=1.11;
3. 在编程中会根据需要合理确定常量与变量的类型并正确使用.
根据变量范围选择不同的类型
4. 理解各种运算符的优先级和结合性,掌握其构成表达式的语法表示和运算规则,会正确计算表达式的值,会根据需要书写正确的 C 表达式.
运算符 的优先级什么的 见链接内:
详情点击链接
-
表达式分为:
- 关系表达式
- 逻辑表达式
- 条件表达式
赋值表达式
用赋值运算符将运算对象连接而成的式子成为赋值表达式k=(j+1);
由于赋值运算符是自右向左运算 所以等价于k=j=1;
关系表达式
关系表达式就是用关系运算符将两个表达式连接起的式子,被连接的表达式可以是算数表达式、关系表达式、逻辑表达式、赋值表达式和字符表达式等
任何一个关系表达式的结果均为两个值:真和假,其中 1 代表真,0 代表假。逻辑表达式
带有&&(与、且) ||(或) !(非)
的表达式- &&
左右两侧都为真时,才是真,一假即为假 - ||
左右两侧一个为真即为真,全假才是假
逗号表达式
一般形式表达式1,表达式2,表达式3...表达式n
当逗号作为运算符使用时是一个双目运算符,其运算优先级是所有运算符中最低的。逗号运算符的运算顺序是自左向右的。a = 2 * 6,a - 4,a + 15; /* 先算 2*6 并赋值给 a,再计算 a-4,最后计算 a+15,最终以 27 作为整个逗号表达式的值。需要注意的是 后两个表达式的值仅做了计算,而并没有赋值给 a 所以 a 的值仍然是 12 */
5. 了解表达式中不同类型数据间的自动转换规则,掌握强制类型转换的使用方法.
C 语言中自动转化规则
-
若参与运算量的类型不同,则先转换成同一类型,然后进行运算
-
转换按数据长度增加的方向进行,以保证精度不降低.如 int 型和 long 型运算时,先把 int 量转成 long 型后再进行运算
- 若两种类型的字节数不同,转换成字节数高的类型
- 若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型
-
所有的浮点运算都是以双精度进行的,即使是两个 float 单精度量运算的表达式,也要先转换成 double 型,再作运算.
-
char 型和 short 型参与运算时,必须先转换成 int 型
-
在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型.
如果右边量的数据类型长度左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入
C 语言强制类型转换规则
强制类型转换 强制类型转换一般格式如下:(类型名)(表达式)
#include <stdio.h>
int main()
{
int sum = 17, count = 5;
double mean;
mean = (double) sum / count;
printf("Value of mean : %f
", mean );
}
这种强制类型转换操作并不改变操作数本身
三、顺序结构程序设计
1. 了解 C 程序中常用的基本语句形式.
语句是一个程序逻辑的体现,它描述了程序.
从程序流程的角度来看,程序可以分为三种基本结构, 即顺序结构、分支(选择)结构、循环结构.
这三种基本结构可以组成所有的各种复杂程序.
C 语言提供了多种语句来实现这些程序结构.
C 程序的执行部分是由语句组成的. 程序的功能也是由执行语句实现的.
C 语句可分为以下五类:
1.表达式语句
其一般形式为:表达式;执行表达式语句就是计算表达式的值
例如:
x=y+z;a=520;赋值语句
2.函数调用语句
其一般形式为: 函数名(实际参数表)
执行函数语句就是调用函数体并把实际参数赋予函数定义中的形式参数,然后执行被调函数体中的语句,求取函数值
调用库函数,输出字符串
例如:
printf("a,b,c"); /*调用名为"printf"的函数*/
3.控制语句
控制语句用于控制程序的流程, 以实现程序的各种结构方式.
它们由特定的语句定义符组成.C 语言有九种控制语句. 可分成以下三类:
- 条件判断语句
if,switch - 循环执行语句
do while,while,for - 转向语句
break,go to,continue,return
4.复合语句
把多个语句用括号{}括起来组成的一个语句称复合语句. 在程序中应把复合语句看成是单条语句,而不是多条语句
例如:
{
x=y+z;
a=b+c;
printf("%d%d",x,a);
}
// 复合语句内的各条语句都必须以分号";"结尾;此外,在括号"}"外不能加分号
5.空语句
只有分号";"组成的语句称为空语句
空语句是什么也不执行的语句
在程序中空语句可用来作空循环体
例如:
while(getchar()!='
');
// 本语句的功能是,只要从键盘输入的字符不是回车则重新输入 这里的循环体为空语句
2. 掌握使用 getchar()和 putchar()标准库函数实现字符数据输入与输出的方法.
getchar()
C 库函数 int getchar(void) 从标准输入 stdin 获取一个字符(一个无符号字符)
C 库函数 int putchar(int char) 把参数 char 指定的字符(一个无符号字符)写入到标准输出 stdout 中
printf("请输入字符:");
c = getchar();
printf("输入的字符:");
putchar(c);
3. 掌握使用 scanf()和 printf()标准函数实现不同类型数据的格式输入与输出的方法,在编程中会根据需要正确输入数据并合理设计输出格式.
C 库函数 int scanf(const char *format, ...) 从标准输入 stdin 读取格式化输入
C 库函数 int printf(const char *format, ...) 发送格式化输出到标准输出 stdout
int a,b;
printf("输入两个数");
scanf("%d%d",&a,&b);
printf("%d,%d",a,b);
输出控制符有:
控制符 说明
%d 按十进制整型数据的实际长度输出。
%ld 输出长整型数据。
%md m 为指定的输出字段的宽度。如果数据的位数小于 m,则左端补以空格,若大于 m,则按实际位数输出。
%u 输出无符号整型(unsigned)。输出无符号整型时也可以用 %d,这时是将无符号转换成有符号数,然后输出。但编程的时候最好不要这么写, 因为这样要进行一次转换,使 CPU 多做一次无用功。
%c 用来输出一个字符。
%f 用来输出实数,包括单精度和双精度,以小数形式输出。不指定字段宽度,由系统自动指定,整数部分全部输出,小数部分输出 6 位,超过 6 位的四舍五入。
%.mf 输出实数时小数点后保留 m 位,注意 m 前面有个点。
%o 以八进制整数形式输出,这个就用得很少了,了解一下就行了。
%s 用来输出字符串。用 %s 输出字符串同前面直接输出字符串是一样的。但是此时要先定义字符数组或字符指针存储或指向字符串,这个稍后再讲。
%x(或 %X 或 %#x 或 %#X) 以十六进制形式输出整数,这个很重要。
4. 掌握使用顺序结构设计简单 C 程序的基本方法.
大概意思就是从上到下,依次执行的程序
四、选择结构程序设计
1. 理解三种 if 语句的语法结构,掌握使用 if 语句设计选择结构程序的方法
// 重点在于小括号里的条件判断
if(a>b)
{
a+=b;
}
2. 理解 switch 语句的语法结构,掌握使用 switch 语句设计多分支选择结构程序的方法
switch(1)
{
case 1 :
printf("1");
break;
case 2 :
printf("2");
break;
default :
printf("No");
}
3. 了解嵌套选择结构语句的语法表示,会分析嵌套选择结构程序的执行过程
选择结构也称分支结构,就是让程序"拐弯",有选择性的执行代码
换句话说,可以跳过没用的代码,只执行有用的代码
if(a>b)
{
printf("a b");
}else{
printf("a <b");
}
4. 会正确分析选择结构程序的执行过程,会合理选用语句形式设计正确的选择结构程序
3 和 4 差不多 不一一作答了 主要看程序怎么写
五、循环结构程序设计
1. 理解 while、do-while 和 for 语句的语法结构,掌握使用三种循环语句设计循环结构程序的方法
while
while(1)
{
printf("我是无限循环!!!!!!!!");
}
do-while
int i=0;
{
printf("我还是无限循环!!!!");
}while(i=0);
for
for (int i=1;i<0;i++)
{
printf("我还是无限循环!!!!");
}
2. 理解 continue 和 break 语句的语法结构,掌握其在循环结构程序中的使用方法
continue 只结束当前循环体
break 退出当前循环体
3. 了解嵌套循环结构语句的语法表示,会正确分析嵌套循环结构程序的执行过程
主要看程序怎么写 不详细叙述
六、数组
1. 掌握一维数组和字符数组的定义、初始化及其元素引用的方法
在 C 中要声明一个数组,需要指定元素的类型和元素的数量
二话不说上代码
// 数组声明
int arr[10];
// 初始化
int arr[3]={1,2,3};
// 没有写数组数量的话 花括号里面的数量就是 [] 里的
int arr[]={1,2,3};
// 访问数组内的元素
printf("%d",arr[2]);
2. 熟悉二维数组的定义、初始化及其元素引用的方法
// 数组声明
int arr[10][20];
// 初始化
1. int arr[3][2]={1,2,3,4,5,6};
2. int arr[3][2]={
{1,2,3},
{4,5,6}
}
// 不写数组 行数量是可以的,因为 数组行数 = 数组元素 / 数组列数
int arr[][2]={1,2,3,4,5,6};
// 访问数组内的元素
printf("%d",arr[2][3]);
//表示访问第二行 第三个 元素
3. 理解字符串的概念,掌握使用字符数组存储和操作字符串的方法,熟悉常用字符串处理函数(puts、gets、strcmp、strlen)的使用方法
字符串:
字符串实际上是使用 null 字符 ' ' 终止的一维字符数组
因此,一个以 null 结尾的字符串,包含了组成字符串的字符
// 字符串数组 声明
char china[6];
// 初始化
char china[6]={'c', 'h', 'i', 'n', 'a', ' '};
// 输出字符串
printf("%s",china);
// 修改字符串数组元素
char china[6]={'c', 'h', 'i', 'n', 'a', ' '};
china[3]='s';
puts()
C 库函数 int puts(const char *str) 把一个字符串写入到标准输出 stdout,直到空字符,但不包括空字符.换行符会被追加到输出中.
char china[6]={'c', 'h', 'i', 'n', 'a', ' '};
puts(china);
// 输出结果: china
gets()
C 库函数 char *gets(char *str) 从标准输入 stdin 读取一行,并把它存储在 str 所指向的字符串中.当读取到换行符时,或者到达文件末尾时,它会停止,具体视情况而定
char china[6];
printf('请输入中国china');
gets(china);
puts(china);
// 输出结果: china
strcmp()
C 库函数 int strcmp(const char *str1, const char *str2) 把 str1 所指向的字符串和 str2 所指向的字符串进行比较
注意:使用此函数要调用 字符串处理库函数
#include <stdio.h>
#include <string.h>
int main ()
{
char str1[15];
char str2[15];
int ret;
strcpy(str1, "abcdef");
strcpy(str2, "ABCDEF");
ret = strcmp(str1, str2);
if(ret < 0)
{
printf("str1 小于 str2");
}
else if(ret 0)
{
printf("str2 小于 str1");
}
else
{
printf("str1 等于 str2");
}
return(0);
}
strlen()
C 库函数 size_t strlen(const char *str) 计算字符串 str 的长度,直到空结束字符,但不包括空结束字符
#include <stdio.h>
#include <string.h>
int main ()
{
char str[50];
int len;
strcpy(str, "This is runoob.com");
len = strlen(str);
printf("|%s| 的长度是 |%d|
", str, len);
return(0);
}
// 输出结果:|This is runoob.com| 的长度是 |18|
再补充一个
strcat()
4. 在编程中会使用数组正确处理同质数据的读写访问操作,会使用字符串处理函数操作字符串
主要看程序怎么写 不详细叙述
七、函数
函数是一组一起执行一个任务的语句
每个 C 程序都至少有一个函数,即主函数 main()
先声明、定义、调用
1. 理解函数定义的语法形式,掌握一般函数的定义方法
函数定义:
int max(int a,int b)
{
int result;
if(a>b)
{
result = a;
}else{
result = b;
}
return result;
}
// 此程序输出大的那个数
函数声明:
在函数声明中,参数的名称并不重要,只有参数的类型是必需的,因此下面也是有效的声明
int max(int,int);
调用函数
int c;
c=max(a, b);
printf("%d",c);
输出结果: 较大的数
2. 理解函数的形式参数与实际参数、函数的返回值的概念和特点
形式参数:
形参就是定义函数时候的参数表,只是定义了参数表的结构和用来引用的名字,并没有具体的内容 在调用结束 形参会消失
实际参数:
实参是调用函数传递的具体数据 在调用结束 实参还会存在
返回值:
返回值把函数的处理结果数据返回给调用函数,即递归调用,所以一般把函数名变量称为返回值,函数的返回值类型是在定义函数时指定的
一个函数可以有返回值,也可以没有返回值
- 没有返回值的函数:功能只是完成一个操作,应将返回值类型定义为 void,函数体内可没有 return 语句.
- 有返回值的函数:函数的最后会有一个返回值 return,可以用来获取该函数执行结果返回给该函数,让外部调用该函数的.
返回值可指定,如果不指定默认返回 None
3. 理解函数调用的语法形式;理解函数原型的概念,掌握其声明方法
在 1. 中讲述了 调用的语法形式和声明方法
函数原型:
函数原型也叫函数声明,还叫引用说明
其目的是实现先调用函数,后定义函数
函数原型类似函数定义时的函数头
为了能使函数在定义之前就能被调用,C++规定可以先说明函数原型,然后就可以调用函数
函数定义可放在程序后面
由于函数原型是一条语句,因此函数原型必须以分号结束
函数原型由函数返回类型、函数名和参数表组成,它与函数定义的返回类型、函数名和参数表必须一致
函数原型不必包含参数的名字,可只包含参数的类型
例如: int area (int, int )
等价于 int area(int a,int b)
说明:系统标准函数并没有在包含文件中定义,而只是提供了函数原型
在调用函数时,系统会正确地调用库函数
注意:函数原型与函数定义必须一致,否则会引起编译错误
4. 理解函数传值调用的参数传递机制和特点,会正确分析函数传值调用的执行过程,掌握使用函数的传值调用实现结构化程序设计的方法
5. 了解函数嵌套调用的概念,会正确分析函数嵌套调用的执行过程
嵌套调用
C 语言中不允许作嵌套的函数定义.
因此各函数之间是平行的,不存在上一级函数和下一级函数的问题
但是 C 语言允许在一个函数的定义中出现对另一个函数的调用
这样就出现了函数的嵌套调用
即在被调函数中又调用其它函数
这与其它语言的子程序嵌套的情形是类似的
其关系可表示如图:
6. 了解递归函数的概念,会正确分析递归函数调用的执行过程
递归函数
一个函数在它的函数体内调用它自身称为递归调用,这种函数称为递归函数
执行递归函数将反复调用其自身,每调用一次就进入新的一层,当最内层的函数执行完毕后,再一层一层地由里到外退出
公式:
//求n!
long factorial(int n){
long result;
if(n==0 || n==1){
result = 1;
}else{
result = factorial(n-1) * n; // 递归调用
}
return result;
}
这是一个典型的递归函数.调用 factorial() 后即进入函数体,只有当 n0 或 n1 时函数才会执行结束,否则就一直调用它自身
由于每次调用的实参为 n-1,即把 n-1 的值赋给形参 n,所以每次递归实参的值都减 1,直到最后 n-1 的值为 1 时再作递归调用,形参 n 的值也为 1,递归就终止了,会逐层退出
7. 了解变量的作用域和生存期的概念,理解局部变量和全局变量的概念,掌握其使用方法;理解自动变量、静态局部变量的特点,掌握其使用方法;了解寄存器变量的使用方法,了解用 extern 声明外部变量的方法,会根据程序中变量的定义位置和声明方式正确分析变量的作用域和生存期
看着都好尼玛难 想想算了吧
八、预处理命令
程序设计语言的预处理的概念:在编译之前进行的处理。
C 语言的预处理主要有三个方面的内容:
- 宏定义;
- 文件包含;
- 条件编译。
预处理命令以符号“#”开头
1. 了解编译预处理的概念、作用.
预处理编译的作用:
- 将源文件中以"include"格式包含的文件复制到编译的源文件中。
- 用实际值替换用"#define"定义的字符串。
- 根据"#if"后面的条件决定需要编译的代码。
2. 理解宏定义命令的语法形式,掌握不带参数以及带参数宏定义的使用方法,会分析宏定义命令在预编译时的宏展开过程.
3. 了解文件包含命令的语法形式,在程序设计中会正确使用文件包含命令
在 C 语言中文件包含是指一个源文件可以将另一个源文件的全部内容包含进来。该命令的作用是在预编译时,将指定源文件的内容复制到当前文件中。文件包含是 C 语言预处理命令三个内容之一。
文件包含有两种格式,分别是:#include "file"
和 #include <file>
一般情况使用引号比较保险
九、指针
1. 了解指针的概念,理解指针运算符(*)
和取地址运算符(&)
的使用特点,掌握指向变量的指针变量的定义、赋值和引用的方法,理解指针的赋值运算和算术运算的规则
*
指针运算符(间接访问)
&
取地址运算符
注意:指针赋值只能是地址。 使用值时要用* 得到地址的内容 而& 可以得到内存地址
// 先声明 同时 初始化 在使用
int a = 3,*p = &a;
printf("%d",*p);
// 结果: 3
// 先声明 后 初始化 在使用
int *p,a = 3;
p = &a;
printf("%d",*p);
// 结果: 3
#include"stdio.h"
void main()
{
int a = 3,b = 2,c = 4,*p = &a,*p1 = &b,*p2 = &c;
printf("%d,%d",*p * *p1,*p * *p2);
}
// 结果: 6 12
#include <stdio.h>
int main ()
{
int var1;
char var2[10];
printf("var1 变量的地址: %p
", &var1 );
printf("var2 变量的地址: %p
", &var2 );
return 0;
}
// 结果
var1 变量的地址: 0x7fff5cc109d4
var2 变量的地址: 0x7fff5cc109de
2. 掌握指向一维数组的指针变量的定义、赋值和引用的方法,会正确运用指针变量间接访问一维数组的元素
double *p;
double arr[10];
p = arr;
一旦您把第一个元素的地址存储在 p 中,您就可以使用*p、*(p+1)、*(p+2)
等来访问数组元素
#include <stdio.h>
int main ()
{
int var = 20; /_ 实际变量的声明 _/
int _ip; /_ 指针变量的声明 _/
ip = &var; /_ 在指针变量中存储 var 的地址 _/
printf("Address of var variable: %p
", &var );
/_ 在指针变量中存储的地址 _/
printf("Address stored in ip variable: %p
", ip );
/_ 使用指针访问值 */
printf("Value of *ip variable: %d
", *ip );
return 0;
}
结果:
Address of var variable: bffd8b3c
Address stored in ip variable: bffd8b3c
Value of *ip variable: 20
3. 掌握指向字符串的指针变量的定义、赋值和引用的方法,会正确运用指针变量间接访问字符串
#include<stdio.h>
void main()
{
char arr[] = "china",*p = arr;
printf("%s,%s",p,p[1]);
}
结果:
china h
4. 理解使用指针变量、数组名作为参数的函数调用的机制和特点,掌握函数的传址调用的使用方法,会正确分析函数传址调用的执行过程,在编程中会根据需要设计合理的传址调用函数并进行正确调用
5. 了解返回指针值的函数的概念,熟悉指针数组、指向指针的指针概念和使用方法,会使用指针数组和二级指针间接访问二维数组元素
#include<stido.h>
int max(int a, int b)
{
int *p;
if(a > b)
{
p = &a;
}else
{
p = &b;
}
return *p;
}
int main()
{
int c = max (3,4);
prinf("%d",c);
}
结果:
4
十、结构体与共用体
tip:
结构体 和结构体变量
- 结构体 是一个类型 类似于 int float double
- 结构体变量 是实实在在的数据 就像 int a = 3; 里的 a
1. 了解和区分结构体和共用体的概念,掌握结构体类型的定义方法,以及结构体变量的定义、初始化和成员引用的方法
结构体和共用体的区别:
结构体和共用体的区别在于:结构体的各个成员会占用不同的内存,互相之间没有影响;而共用体的所有成员占用同一段内存,修改一个成员会影响其余所有成员。
结构体占用的内存大于等于所有成员占用的内存的总和(成员之间可能会存在缝隙),共用体占用的内存等于最长的成员占用的内存。共用体使用了内存覆盖技术,同一时刻只能保存一个成员的值,如果对新的成员赋值,就会把原来成员的值覆盖掉。
结构体的定义,初始化,引用示例:
<!-- 不重定义结构体变量名 -->
#include <stdio.h>
#include <string.h>
struct people
{
char id[10];
char name[100];
};
int main()
{
struct people sister;
strcpy(sister.id, "1");
strcpy(sister.name, "sister");
printf("%s%s", sister.id, sister.name);
}
结果:
1sister
<!-- 重定义结构体变量名 -->
#include<stdio.h>
#include<string.h>
typedef struct // 重定义变量名 typedef
{
char title[50];
char author[50];
int id;
} books;
int main()
{
books book1;
strcpy(book1.title,"c++");
strcpy(book1.author,"lambert");
id = 1;
printf("id is:%d
title is:%s
author is:%s",book1.id,book1.title,book1.author);
}
结果:
id is:1
title is:c++
author is:lambert
2. 掌握结构体数组的定义、初始化和引用数组元素及其成员的方法,会正确运用结构体数组处理异质数据的存储和访问操作
#include<stdio.h>
#include<string.h>
typedef struct
{
char xingbie[20];
int age;
} people;
int main()
{
people people[10]; // 这个就是结构体数组 数组内每个元素都是 结构体
for(int i = 0;i < 10;i++)
{
if(i % 2 ==0)
strcpy(people[i].xingbie,"man");
else
strcpy(people[i].xingbie,"woman");
people[i].age = i;
}
for(int i = 0;i < 10;i++)
{
printf("xingbie is :%6s age is :%3d
",people[i].xingbie,people[i].age);
}
}
结果:
xingbie is : man age is : 0
xingbie is : woman age is : 1
xingbie is : man age is : 2
xingbie is : woman age is : 3
xingbie is : man age is : 4
xingbie is : woman age is : 5
xingbie is : man age is : 6
xingbie is : woman age is : 7
xingbie is : man age is : 8
xingbie is : woman age is : 9
3. 掌握指向结构体类型数据的指针变量的定义、初始化和引用方法,会正确运用指向结构体数据的指针变量间接访问结构体数据及成员,熟悉结构体指针作为参数的函数调用方法
结构体指针 要在结构体变量后面进行 声明
例如:
#include<stdio.h>
int main()
{
typedef struct
{
int id;
char name[100];
} books,*p = &books;
}
注意:
结构体变量名和数组名不同,数组名在表达式中会被转换为数组指针,而结构体变量名不会,无论在任何表达式中它表示的都是整个集合本身,要想取得结构体变量的地址,必须在前面加&,所以给 pstu 赋值只能写作:
struct stu *pstu = &stu1;
而不能写作:
struct stu *pstu = stu1;
通过结构体指针可以获取结构体成员,一般形式为:
(*pointer).memberName
或者:pointer->memberName
第一种写法中,.
的优先级高于*
,(*pointer)
两边的括号不能少。如果去掉括号写作_pointer.memberName
,那么就等效于_(pointer.memberName)
,这样意义就完全不对了。
第二种写法中,->
是一个新的运算符,习惯称它为“箭头”,有了它,可以通过结构体指针直接取得结构体成员;这也是->
在 C 语言中的唯一用途。
上面的两种写法是等效的,我们通常采用后面的写法,这样更加直观。
例如:
#include <stdio.h>
int main(){
struct{
char *name; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
} stu1 = { "Tom", 12, 18, 'A', 136.5 }, *pstu = &stu1;
//读取结构体成员的值
printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!
", (*pstu).name, (*pstu).num, (*pstu).age, (*pstu).group, (*pstu).score);
printf("%s的学号是%d,年龄是%d,在%c组,今年的成绩是%.1f!
", pstu->name, pstu->num, pstu->age, pstu->group, pstu->score);
return 0;
}
结果:
Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!
Tom的学号是12,年龄是18,在A组,今年的成绩是136.5!
#include <stdio.h>
struct stu{
char *name; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
}stus[] = {
{"Zhou ping", 5, 18, 'C', 145.0},
{"Zhang ping", 4, 19, 'A', 130.5},
{"Liu fang", 1, 18, 'A', 148.5},
{"Cheng ling", 2, 17, 'F', 139.0},
{"Wang ming", 3, 17, 'B', 144.5}
}, *ps;
int main()
{
//求数组长度
int len = sizeof(stus) / sizeof(struct stu);
printf("Name Num Age Group Score
");
for(ps=stus; ps<stus+len; ps++){
printf("%s %d %d %c %.1f
", ps->name, ps->num, ps->age, ps->group, ps->score);
}
return 0;
}
结果:
Name Num Age Group Score
Zhou ping 5 18 C 145.0
Zhang ping 4 19 A 130.5
Liu fang 1 18 A 148.5
Cheng ling 2 17 F 139.0
Wang ming 3 17 B 144.5
结构体变量名代表的是整个集合本身,作为函数参数时传递的整个集合,也就是所有成员,而不是像数组一样被编译器转换成一个指针。如果结构体成员较多,尤其是成员为数组时,传送的时间和空间开销会很大,影响程序的运行效率。所以最好的办法就是使用结构体指针,这时由实参传向形参的只是一个地址,非常快速。
结构体指针为参数时的使用方法:
#include <stdio.h>
struct stu
{
char *name; //姓名
int num; //学号
int age; //年龄
char group; //所在小组
float score; //成绩
}stus[] = {
{"Li ping", 5, 18, 'C', 145.0},
{"Zhang ping", 4, 19, 'A', 130.5},
{"He fang", 1, 18, 'A', 148.5},
{"Cheng ling", 2, 17, 'F', 139.0},
{"Wang ming", 3, 17, 'B', 144.5}
};
void average(struct stu *ps, int len);
int main(){
int len = sizeof(stus) / sizeof(struct stu);
average(stus, len);
return 0;
}
void average(struct stu *ps, int len)
{
int i, num_140 = 0;
float average, sum = 0;
for(i=0; i<len; i++){
sum += (ps + i) -> score;
if((ps + i)->score < 140) num_140++;
}
printf("sum=%.2f
average=%.2f
num_140=%d
", sum, sum/5, num_140);
}
结果:
sum=707.50
average=141.50
num_140=2
4. 了解共用体类型的定义方法,以及共用体变量的定义、初始化和成员引用的方法
5. 会正确使用 typedef 语句定义新的类型名
在十大类第一节已详细说明,在此就不赘述了
十一、位运算
1. 理解各种位运算符的含义,掌握各种位运算的运算规则和特点
2. 会正确分析简单的位运算程序,会正确使用位运算实现清零、置 1、保留、移位等功能