软协第一次考核总结

通过这次考核,我发现自己存在很多问题,C语言基础不够扎实,存在知识盲区,还有一些知识点理解不够深刻,应该再好好研究 C Primer Plus 这本书,扎实基础,同时要多刷题,强化代码能力。

软协的门牌号是:FZ131!!!记牢记牢记牢!!!

1. 正负数在计算机中存储 : 

十进制的整数 22 和 -22 在 8 位计算机中的存储分别为(  )

A. 11101010,00010110                           

B. 00010110,11101010

C. 00010110,10010110                         

D. 10010110,11101010

22转化为二进制为00010110,负数在计算机中,以补码的形式存储,22的补码为,从右向左数的0和第一个出现的1不变,其余取反,所以是11101010,选B。

2. 浮点型数据比较

下面代码会输出 c!=d c=1.900000,d=1.900000。分析原因并给出修改方案

#include<stdio.h>

int main()
{
    double a = 1.6;
    double b = 0.3;
    double c = 1.9;
    double d = a + b;
    if (c == d)
    {
        printf("c==d");
    }
    else
        printf("c!d c=%lf d=%lf", c, d);
    return 0;
}

 任意一个二进制浮点数V可以表示成 (-1)^(s)*M*2^(E) 的形式。

(-1)^(s)表示符号位(s=0时V为正数,s=1时V为负数)

M表示有效数字,大于等于1,小于2

2^(E)表示指数位

 如十进制的9.0,写成二进制形式为1001.0,相当于1.001*2^(3)  =  (-1)^(0)*1.001*2^(3)   (s=0,M=1.001,E=3)

所以计算机中存储的浮点型数据并不准确,只是一个大概值,所以 d = a + b 在1.9 附近,不等于c,所以c != d 。

修改方案:使用fabs函数,fabs()函数是返回浮点数的绝对值的一个函数,定义在math.h头文件中。

3. 自动类型转换:

(多选)下列关于自动类型转换描述正确的是(    )

A. int 型和 int 型运算时,不会发生自动类型转换

B. float 型和 float 型运算时,不会发生自动类型转换

C. long 型和 float 型运算时,会发生自动类型转换

D.long 型和 int 型运算时,会发生自动类型转换

必定的转换:char型、short型数据运算时必定先转换为int型,float型数据运算时转换成double型。

不同类型的转换: int 型和 long 型运算时,先将 int 型直接转换成 long 型,最终结果为 long 型。float 型和 int 型运算时,先将float 型转换成 double 型,int 型转换成 double 型,最终结果为 double 型。

所以选ACD.

4. 输出 a > b : 

(1)

if(a>b)
   max=a;
else max=b;

(2) 

int max;
max=a>b ? a : b ;

 5. strlen 和 sizeof 的区别:

strlen:计算字符串的长度的函数,遇到第一个NULL(‘\0’)为止,不包括‘\0’, 时间复杂度为O(n)

sizeof: 计算变量、对象或类型所占字节数的多少,是一个运算符,时间复杂度为常数

char s1[] = "hello";

char* s2 = "hello";

char s3[10] = ''hello";

sizeof(s1) = 5               strlen(s1) = 5

sizeof(s2) = 4               strlen(s2) = 5

sizeof(s3) = 10             strlen(s3) = 5

s2是一个指针,对于指针,sizeof所得值,在32位系统是4,在64系统是8

strlen,不管是数组还是指针,只要遇到第一个‘\0’就为止,hello字符串是这样的{‘h’, ‘e’,‘l’,‘l’,‘o’,‘\0’}的所以strlen(“hello”) = 5

sizeof:用法,sizeof(int)、sizeof(2)、sizeof(2+1)、sizeof(f())(int f(),f是一个函数,sizeof是返回值类型的大小,返回值是void,是不能使用sizeof的),但是位域不能被sizeof计算。sizeof是一个关键字不是函数,发生在编译时刻,所以可以用作常量表达式。

    总结,当参数分别如下时,sizeof返回的值表示的含义如下:
    数组——编译时分配的数组空间大小;
    指针——存储该指针所用的空间大小(在32位系统是4,在64系统是8);
    类型——该类型所占的空间大小;
    对象——对象的实际占用空间大小;
    函数——函数的返回类型所占的空间大小。函数的返回类型不能是void

sizeof只关心这块内存的大小,不关心这块内存存放了什么数据,strlen只关心这块内存存放的数据,不关心这块内存的大小,直到遇到第一个NULL为止

6. 链表访问数据域:

-> : 指针类型

. : 结构体类型

所以,访问p结点的数据域:p->data,还可以(*p).data 。

7. 指针与数组:

int a[5] = { 6,3,4,7,9 };

int* p = a;

写出++*p,*p++,*(p++),(*p)++,*++p,*a++,*++a的对应的值

(注:若用程序测试,记住一个一个测,要不然p的值已经发生变化)

++与*同时出现,并且挨在一起的时候,自右向左运算,

*:取值运算符,与指针组合使用,获得指针所指向变量的值,a是数组,所以*a报错,没有结果。

++*p :先取p的值,p指向数组a的首地址,*p是6,++*p为7

*p++:先取p的值,*p++后还是++前的值,所以*p++为6

*(p++):先进行p++,p还是指向数组a的首地址,取首地址的值,所以*(p++)为6

(*p)++:先取数组a的首地址,(*p)为6,(*p)++,还是++前的结果,所以(*p)++为6

*++p:先++p,p指向a[2], 所以*++p为3

总结:只有++(p*)、(*p)++、++*p,指针位置不变,改变数组的原始数值

其他情况都是指针指向下一个,指针的位置+1。

8. 文件读取

下面的程序功能是:新建test.txt文件,为其写入字符串“ok”,并从中读取出来。现已知下面程序无法实现该功能,请在横线上填写一行代码,完善此功能。

#include<stdio.h>
int main()
{
	FILE* fp = fopen("test.txt", "a+");
	char s[20] = "ok";
	fputs(s, fp);
	char t[20];
	fseek(fp, 0, 0); //所需要填的代码
	fscanf(fp, "%s", t);
	puts(t);
	fclose(fp);


	return 0;
}

9.读入文件,链表的增删改查

要求:

(1) 链表存储 

(2) 从本地文件“member.txt” 中读取软协成员信息,并展示全部成员信息(按学号排序后展示)

(3) 通过姓名查询出指定成员并删除成员

(4) 添加新成员

(5) 修改成员的联系方式

#include<stdio.h>
#include<conio.h>
#include<string.h>
#include<stdlib.h>

typedef struct member   
{
	char name[10];
	char num[15];
	char dir[10];
	char pho[15];
	struct member* next;
}Mem;

int CreatRear(Mem** h);
void Delete(Mem** h);
void show(Mem* h);
Mem* Modify(Mem* h);
Mem* Sort(Mem* h);
int SaveFile(Mem* h);
int ReadFile(Mem **h);

int main()   //主函数
{
	int select = 1;
	Mem* head = NULL;
	ReadFile(&head);
	while (select != 0)
	{
		printf("-------------------------\n");
		printf("---------请选择----------\n");
		printf("---------1.数据录入------\n");
		printf("---------2.数据删除------\n");
		printf("---------3.数据修改------\n");
		printf("---------4.数据排序------\n");
		printf("---------5.数据展示------\n");
		printf("----------请选择:-------\n");
		scanf("%d", &select);
		switch (select)
		{
		case 1:
			CreatRear(&head);
			break;
		case 2:
			Delete(&head);
			break;
		case 3:
			Modify(head);
			break; 
		case 4:
			Sort(head);
			break;
		case 5:
			show(head);
			break;

		default:
			break;

		}
	}
	return 0;

}

int ReadFile(Mem **h)   //读取文件
{
	FILE*  fp;
	Mem *head,*p,*q=NULL;
	if((fp=fopen("D:\\c\\xi\\members.txt","r+"))==NULL)
	{
		printf("打开失败!");
		exit(-1);
	}
	
	//fp=fopen("D:\\c\\xi\\members.txt","r+");
	while(!feof(fp))
	{
		
		p=(Mem*)malloc(sizeof(Mem));
		if(q==NULL)
		{
			*h=p;
			q=*h;
		}
		else
			q->next=p;
			
		p->next=NULL;
		fscanf(fp,"%s",p->name);
	    fscanf(fp,"%s",p->num);
	    fscanf(fp,"%s",p->dir);
	    fscanf(fp,"%s",p->pho);
//	    printf("%s %s %s %s\n",p->name,p->num,p->dir,p->pho);
      	q=p;
    } 
	fclose(fp);
	return 1;
	
 } 



int CreatRear(Mem **h)  //尾插添加新成员
{
	char mname[10];
	char mnum[15];
	char mdir[10];
	char mpho[15];
	Mem* p=NULL, * q=NULL;

	printf("请输入信息:\n");
	printf("姓名:");
	scanf("%s", mname);
	printf("学号:");
	scanf("%s", mnum);
	printf("方向:");
	scanf("%s", mdir);
	printf("电话:");
	scanf("%s", mpho);
	getch();

	p = (Mem*)malloc(sizeof(Mem));
	if (p == NULL)
		return 0;
	strcpy(p->name, mname);
	strcpy(p->num, mnum);
	strcpy(p->dir, mdir);
	strcpy(p->pho, mpho);

	p->next = NULL;

	if (*h == NULL)
		*h = p;
	else
	{
		q = *h;
		while (q->next != NULL)
			q = q->next;
		q->next = p;
	}
	return 1;

}



void Delete(Mem** h)  //删除成员信息
{
	char mname[10];
	Mem* p = NULL,*q = NULL;
	if (q == *h)
		*h = q->next;
	else
	{
		p = *h;
		while (p->next != q) p = p->next;
		p->next = q->next;
	}
	free(q);
	getch();

}



Mem* Modify(Mem* h)    //修改成员信息
{
	Mem* p = NULL;
	char mname[10];
	printf("请输入修改后的电话:");
	char mpho[15];
	scanf("%s", mpho);
	strcpy(p->pho, mpho);
	getch();

	return h;
}


void show(Mem* h)  //展示成员信息
{
	Mem* p;
	p = h;
	printf("信息如下:\n");
	printf("姓名      学号     方向       电话       \n");
	
	while (p != NULL)
	{
		printf("%s\n%s\n%s\n%s\n", p->name, p->num, p->dir, p->pho);
		p = p->next;
	}
	
	getch();
}


Mem* Sort(Mem* h)   //按成员的学号排序
{
	Mem* h1, * p1, * p2, * q;
	h1 = h;
	h = h->next;
	h1->next = NULL;
	while (h!= NULL)
	{
		q = h;
		h = h->next;
		p1 = p2 = h1;
		while (p2 != NULL)
		{
			if (strcmp(q->num, p2->num) < 0)
				break;
			p1 = p2;
			p2 = p2->next;
		}
		if (p1 == p2)
		{
			q->next = p2;
			h1 = q;
		}
		else
		{
			p1->next = q;
			q->next = p2;
		}
	}
	getch();
	return h1;
}


int SaveFile(Mem* h)   //保存成员信息至文件
{
	Mem* p;
	FILE* fp;
	fp = fopen("D:\\c语言\\members .txt", "wt");
	p = h;
	while (p != NULL)
	{
		fwrite(p, sizeof(Mem), 1, fp);
		p = p->next;
	}
	fclose(fp);
	getch();
	return 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值