目录
结构体
struct student {
char name[20];
int num;
float score;
}
struct student st,*p;
p=&st;
则下面的语句正确的是
A)st->num=1001;B)p.num=2001; C)st.name="Zhangsan";D)(*p).score=78
a选项应该为st.num ;b选项应该为p->num ;c选项不能给数组整体赋值;只有d正确
typedef struct的时候,为什么可以有两个名称,两个名称的区别?
typedef作用是给类创建一个【别名】,下面是你给的代码:
typedef struct tagXX
{
} XX;
其实这段代码相当于:
struct tagXX
{
};
typedef struct tagXX XX;
这里面,tagXX是这个结构体的本名,XX只是struct tagXX的别名。
然后你可以用XX来定义变量:
XX a; /*相当于struct tagXX a; */
这样代码更简洁了。
结构体指针二
struct worker
{
int no;
char *name;
}work,*p=&work;
则下面的语句错误的是(D)
A. work.no; B. (*p).no; C. p->no; D. work->no;
结构体变量访问成员变量引用方式用 “.” ,而结构体指针采用 “ -> ” ,因此AC不对;
B项 (*p)表示结构体变量,因此可以用 “ . ”;
D项应该为 work.no
指针连接char数组
void f(char *a,char *b)
{
while(*a++);
*a--;
//or while(*(++a));
while(*b)
*a++=*b++;
*a=0;
}
注意 自加自减运算符,经过循环之后 指向的值!
操作文件
Question describe:
34.某学校组织《共产党的历史知识竞赛》,已知文本文件f1.txt中存放了所有报名参加比赛学生的信息,具体数据及存放格式为每行存放一个学生的数据,共有4项,依次为:姓名(不超过10个字符)、性别(整数:0为男,1为女):年龄(整数)、班号(不超过6个字符),其间用空格分隔。请编写程序,读出文件中的内容,再按筛选条件筛选后以文本方式存放到文件f2.txt中。
筛选条件:
同一班中只取一名年龄最小的男学生和一名年龄最小的女学生。
同班同性别同年龄的学生按先报名先取的原则。(中国地质大学2018年初试题)
Code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct
{
char name[15];
int sex,age;
char clas[10];
} STU;
int main()
{
int i=0,j;
STU st[10000];
FILE *fp;///FILE是一个数据结构,用于访问一个流。每个流都会对应一个FILE结构体
fp=fopen("f1.txt","r");//read 读取文件
if(!fp)
exit(0);///头文件 #include<stdlib.h>
while(!feof(fp))//feof()判断是否到文件结束
{
fscanf(fp,"%s %d %d %s",st[i].name,&st[i].sex,&st[i].age,st[i].clas);
i++;
}
fclose(fp);
STU str[10000];//按照题要求的筛选条件,用于其存储并输出
int k=0;
str[k]=st[0];//先传进去第一个数据
k=1;//
int m=0;
for(j=0; j<i; j++) //原数组 st[]
{
for(m=0; m<k; m++) //最后筛选出来的数组 str[]
{
if(strcmp(str[m].clas,st[j].clas)==0&&str[m].sex==st[j].sex)
{
if(str[m].age>st[j].age)
str[m]=st[j];
break;//剪枝 在str[]中更新之后就可以跳出str[]的遍历了
}
}
if(m==k)//str[]中没有st[j] 的班级,需要加入到筛选之后的数组
str[k++]=st[j];
}
fp=fopen("f2.txt","w");// 若存在f2.txt,就从头写入,否则创建文件
for(int i=0; i<k; i++)
{
fprintf(fp,"%10s%3d%2d%10s\n",str[i].name,str[i].sex,str[i].age,str[i].clas);
}
fclose(fp);//记得关闭
return 0;
}
Operating result:
Supplement:
“r”:以只读的形式打开文本文件(不存在则出错)
“w”:以只写的形式打开文本文件(若不存在则新建,反之,则从文件起始位置写,覆盖原内容)
“a”:以追加的形式打开文本文件(若不存在,则新建;反之,在原文件后追加)
“r+”:以读写的形式打开文本文件(读时,从头开始;写时,新数据只覆盖所占的空间)
“wb”:以只写的形式打开二进制文件
“rb”:以只读的形式打开二进制文件
“ab”:以追加的形式打开一个二进制文件
“rb+”:以读写的形式打开二进制文件。
“w+”:首先建立一个新文件,进行写操作,然后从头开始读(若文件存在,原内容将全部消失)
“a+”:功能与”a”相同。只是在文件尾部追加数据后,可以从头开始读
“wb+”:功能与”w+”相同。只是在读写时,可以由位置函数设置读和写的起始位置
“ab+”:功能与”a+”相同。只是在文件尾部追加数据之后,可以由位置函数设置开始读的起始位置
强制转换数据类型
运行下面程序
#include<stdio.h>
int main()
{
double d;
float f;
long l;
int i;
d=20/3;
printf("d=%lf 1\n",d);
d=20/3.0;
printf("d=%lf 2\n",d);
d=(double)20/3;
printf("d=%lf 3\n",d);
d=double(20/3);
printf("d=%lf 4\n",d);
d=(double)(20/3);
printf("d=%lf 5\n",d);
i=f=l=d=20/3;
printf("i、f、l、d are respectively %d %ld %.1f %.1f \n",i,l,f,d);
return 0;
}
Operating answer:
可以看到第二第三完成了类型转换 int -> double
d=20/3.0;
printf("d=%lf 2\n",d);
d=(double)20/3;
printf("d=%lf 3\n",d);可以看到第四第五 d输出都是6.000000 原因是 20/3 加了括号,所以先执行,结果算出来是 6,然后再转换为double类型就是6.000000
d=double(20/3);
printf("d=%lf 4\n",d);
d=(double)(20/3);
printf("d=%lf 5\n",d);
宏定义
ABCD返回值最大的是C
#include<stdio.h>
#include<iostream>
using namespace std;
#define CANBERRA(x,y) ((x-y)/(x+y))
int main()
{
cout<<CANBERRA (3.0,2.0)<<endl; //A
cout<<CANBERRA (4.0,1.0)<<endl; //B
cout<<CANBERRA (1.0+2.0,0.0+2.0)<<endl; //C
cout<<CANBERRA (1.0+2.0,1.0+1.0)<<endl; //D
return 0;
}
Operating answer:
A. 1.0/5.0 =0.2 B.3.0/5.0 =0.6
C. 宏定义替换后 (1.0+2.0-0.0+2.0)/(1.0+2.0+0.0+2.0) =1.0
D.宏定义替换后 (1.0+2.0-1.0+1.0)/(1.0+2.0+1.0+1.0) =0.6
c程序执行过程是从哪开始到哪里结束?
一个c程序的执行是从“main()”函数开始到“main()”函数结束,但是当代码中出现了exit函数,则是直接结束程序。