周学习总结2

 一.结构学习

1.枚举    枚举是一种用户定义的数据类型,它用关键字enum以如下语法来声明:
enum 枚举类型名字{名字0....名字n} ;
    枚举类型 名字通常并不真的使用,要用的是在大括号里的名字,因为它们就是就是常量符号,它们的类型是int,值则依次从0到n。如:enum colors { red, yellow, green }就创建了三个常量, red的值是0,yellow是1, 而green是2。
    当需要一些可以排列起来的常量值时,定义枚举的意义就是给了这些常量值名字。  
    声明枚举量的时候也可以指定值    例如:enum COLOR { RED=1, YELLOW, GREEN = 5}; 

#include
enum color { red, yellow, green };

void f(enum color c);

int main(void) {
	enum color t = red;
	scanf("%d", &t);
	f(t);
	return 0;
}

void f(enum color c) {
	printf("%d", c);
}

注:自动计数的枚举

#include
enum COLOR { red, yellow, green,NumCOLORS };


int main(int argc ,char* argv[]) {
	
	int color = -1;
	char* ColorNames[NumCOLORS] = {
		"red","yelloe","green",
	};
	char* colorName = NULL;
	printf("输入喜欢颜色的代码");
	scanf("%d", &color);
	if (color >= 0 && color < NumCOLORS) {
		colorName = ColorNames[color];
	}
	else {
		colorName = "umknown";
	}
	printf("你喜欢的颜色是%s\n", colorName);
	return 0;
}

方便建立数组或遍历枚举量

2.结构

数组是一组具有相同类型的数据的集合。但在实际的编程过程中,我们往往还需要一组类型不同的数据,例如对于学生信息登记表,姓名为字符串,学号为整数,年龄为整数,所在的学习小组为字符,成绩为小数,因为数据类型不同,显然不能用一个数组来存放,结构便可以解决这个事情。

struct 结构体名{
    结构体所包含的变量或数组
};

结构体是一种集合,它里面包含了多个变量或数组,它们的类型可以相同,也可以不同,每个这样的变量或数组都称为结构体的成员(Member)。

int、float、char 等是由C语言本身提供的数据类型,不能再进行分拆,我们称之为基本数据类型;而结构体可以包含多个基本类型的数据,也可以包含其他的结构体,我们将它称为复杂数据类型或构造数据类型。

结构体变量

struct stu{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在学习小组
    float score;  //成绩
};

 其中stu是结构体名,它包含了 5 个成员,分别是 name、num、age、group、score。结构体成员的定义方式与变量和数组的定义方式相同,只是不能初始化。
  (1)  结构和数组有点像

  (2)数组用运算符和下标访问其成员a[0]=l0

(3)结构用 “  . ”运算符和名字访问其成员

today.day                                pl.x

student.firstName                   pl.y

#include
struct date {
	int year;
	int mouth;
	int day;
};
int main(void) {
	struct date today;
	today = (struct date){ 2021,11,21 };
	struct date day;
	day = today;
	day.year = 2018;
	printf("Today is %d-%d-%d.\n", today.year, today.mouth, today.day);
	printf("The day is %d-%d-%d.\n", day.year, day.mouth, day.day);
	return 0;
}

%i:有符号十进制整数(与%d相同)

注意大括号后面的分号;不能少,这是一条完整的语句。

struct stu stu1, stu2;

定义了两个变量 stu1 和 stu2,它们都是 stu 类型,都由 5 个成员组成。注意关键字不能少struct。

也可以在定义结构体的同时定义结构体变量:

struct stu{
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在学习小组
    float score;  //成绩
} stu1, stu2;

结构体的各个成员在内存中是连续存储的,和数组非常类似,例如上面的结构体变量 stu1、stu2 的内存分布如下图所示,共占用 4+4+4+1+4 = 17 个字节。

 以下是一个例子,运行可得Tom的资料。

#include
int main() 
{

	
struct{  //没有写 stu
    char *name;  //姓名
    int num;  //学号
    int age;  //年龄
    char group;  //所在学习小组
    float score;  //成绩
} stu1
    ;stu1.name="tom";
    stu1.num=1;
    stu1.age=18;
    stu1.group=9;
    stu1.score=100;
    printf("%s的学号是%d,年龄是%d,在%d组,今年的成绩是%.1f!\n",
	 stu1.name, stu1.num, stu1.age, stu1.group, stu1.score);
	return 0;
}

以下是翁恺老师课上讲的一个例子,但是在编译器里出现了一些问题

#include
#include
#define bool int
struct date {
	int year;
	int month;
	int day;
};

bool isLeap(struct date d)
int numberOfDays(struct date d);

int main(int argc, char const* argv[])
{
	struct date today, tomorrow;

	printf("Enter today is date (year month day)");
	scanf("%d %d %d", &today.year, &today.month, &today.day);

	if (today.day != numberOfDays(today)) {
		tomorrow.day = today.day + 1;
		tomorrow.month = today.month;
		tomorrow.year = today.year;
	}
	else if(today.month==12){
		tomorrow.day = 1;
		tomorrow.month = 1;
		tomorrow.year = today.year + 1;
	}
	else {
		tomorrow.day = 1;
		tomorrow.month = today.month;
		tomorrow.year = today.year;
	}

	printf("Tomorrow is date %d-%d-%d.", tomorrow.year, tomorrow.month, tomorrow.day);


	return 0;
}

int numberOfDays(struct date d)
{
	int days;

	const int daysPerMonth[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };

	if (d.month == 2 && isLeep(d)) {
		days = 29;
	}
	else {
		days = daysPerMonth[d.month - 1];
	}

	return days;
}

bool isLeep(struct date d)
{
	bool leap = false;

	if ((d.year % 4 == 0 && d.year % 100 != 0) || d.year % 400 == 0)
	{
		leap = true;
	}
	return leap;
}

周学习总结2_第1张图片

 还在解决和学习这些问题中

二.练习题

1.清空数组

#include
#include
int main(int argc, char* argv[])
{
	char str[20];
	memset(str,00,sizeof(str));//清空数组每一项 ,让他们变成0
	//memset(要清空的名字,清空变成什么,清空的长度) 
	int i;
	for(i=0;i

memset函数的使用,memset(要清空的名字,清空变成什么,清空的长度)

2.复习大小写字符转换

#include
int main()
{
	char a[100];
	int i;
	gets(a);
//	scanf("%s",&a);
	//printf("%s\n",a);
//	puts(a);
	for(i=0;a[i]!='#';i++){
	
		if(a[i]>='a'&&a[i]<='z')
		{
			a[i]-=32;
		}
		 if(a[i]>='A'&&a[i]<='Z')
		{
			a[i]+=32;
		}
				//printf("%s\n",a);

}
	for(i=0;a[i]!='#';i++){
        printf("%c",a[i]);
}
	//	printf("%s\n",a);

	
	return 0;
}

检验对ASCII码值的掌握,大小写字符ASCII码值相差32.

3.malloc函数定义数组

#include
#include//malloc函数所在的头文件 
int main()
{
	int number;
	scanf("%d",&number);
	//int a[number];
	int *a;
  //	char *p = (char *)malloc(100);
      a=(int*)malloc(number*sizeof(int));//(number*4)

	int i,j;
	for(j=0;j

malloc()

在堆内存分配了100个字节的内存,返回这块内存的首地址,
把地址强制转换成char *类型后赋给char *类型的指 针变量p;
同时告诉我们这块内存将用来存储char类型的数据。你只能通过指针变量p来操作这块内存,
这块内存 本身没有名字,对它的访问是匿名访问。
但是,不一定每次malloc函数都能成功分配到内存。
既然malloc函数申 请内存存在不成功的可能,那我们在使用指向这块内存的指针时,
必须用if( NULL != p)语句上来验证内存分 配确实成功了。

free()

既然有分配,那就必须有释放,不然的话,有限的内存就会用光,
而没有释放的内存却占用空间,与malloc对应 的就是free函数了。
free函数只有一个参数,就是所要释放的内存块的首地址(指针)。
按上例,则 为:free§.free函数其实它就做了一件事:
斩断指针变量和这块内存的对应关系。
free函数就是把这块内存和p 之间的关系斩断;p本身的值并没有改变或者消失,
即指针变量p本身保存的地址并没有改变,那块被释放的内存 里面保存的值也没有改变。
这就是free函数的功能,一个malloc对应一个free,是一夫一妻制。
在使用free(p) 函数内存释放后,指针变量p本身保存的地址并没有改变,
那我们必须需重新把p的值变为NULL:p = NULL。
如 果没有把该指针置NULL,这个指针就成为了“悬空指针”,这是很危险的,且也是经常出错的地方。

只是看了一下理论,并没有掌握会运用

4.删除字符

实现一个删除字符串中的指定字符的简单函数。其中char *str是传入的字符串,c是待删除的字符。函数delchar的功能是将字符串str中出现的所有c字符删除。

#include
#define MAXN 20

void delchar1(char* str, char c)//做
{
    int i, j;
    int t = 0;
    for (i = 0; i < MAXN; i++)
    {
        if (str[i] == c) {
            for (j = i; j < (MAXN - i); j++) {
                str[j] = str[j + 1];
            }
            i--;
        }
    }
}
void delchar2(char* str, char c)//答案
{
    int i, j;
    int t=0;
    for (i = MAXN - 1; i >= 0; i--)
    {
        if (str[i] == c)
        {
            for (j = i; j < (MAXN - i); j++) {
                str[j] = str[j + 1];
            }
            t++;//几个重复的
        }
    }
}
//删除函数的俩个for循环一个后往前遍历一个前往后遍历
int main(int argc, char* argv[])
{
    char str[MAXN], c;

    scanf("%c\n", &c);
    //ReadString(str);
    gets(str);
    delchar1(str, c);
    printf("%s\n", str);
    delchar2(str, c);
    printf("%s\n", str);

    return 0;
}

5.俩点之间距离

其中用户传入的参数为平面上两个点的坐标(x1, y1)和(x2, y2),函数dist应返回两点间的距离。

#include
#include
double dist(double x1, double  y1, double  x2, double y2)
{
	double   a, b;
	double dist;
	a = x1 - x2;
	b = y1 - y2;
	dist = sqrt(a * a + b * b);
	return  dist;
}
int main005(int argc, char* argv[])
{
	double x1 = 0;
	double x2 = 0;
	double y1 = 0;
	double y2 = 0;
	scanf_s("%lf %lf %lf %lf", &x1, &y1, &x2, &y2);
	printf("length=%.2f", dist(x1, y1, x2, y2));
	return 0;
}

6.ASCII码值排序字符,并删除重复

上周有问题的地方,经过学姐指导,明白了是数组长度的控制不当导致会有乱码,成功写出了

#include
int main()
{
	char s[100];
	int i, j, k, cnt = 0;
	char t;
	memset(s, 0, sizeof(s));//sizeof()计算字节大小
	//初始化数组
	gets(s);
	i = 0;
	//计算数组长度
	while (s[i] != '\0') {
		i++;
		cnt++;
	}

	//输出数组
	for (i = 0; i < cnt; i++) {
		printf("%c", s[i]);
	}
	printf("\n");
	printf("\n");


	//利用冒泡原理,ASCII值排序
	for (j = 0; j < cnt; j++)
	{

		for (i = j + 1; i < cnt; i++)
		{
			if (s[j] > s[i]) {
				t = s[i];
				s[i] = s[j];
				s[j] = t;
			}
		}
	}

	//输出数组
	for (i = 0; i < cnt; i++)
	{
		printf("%c", s[i]);

	}
	printf("\n");
	printf("\n");


	//删重复,覆盖前一个
	for (j = 0; j < cnt; j++)
	{

		for (i = j; i < cnt; i++)
		{
			if (s[j + 1] == s[j])
			{
				for (k = j; k < cnt; k++)
				{
					s[k] = s[k + 1];
				}
				cnt--;
			}
		}
	}

	//赋给b数组
	int c = 0;
	char b[20];
	for (i = 0; i < cnt; i++)
	{
		if (s[i] != s[i + 1])
		{
			b[c] = s[i];
			c++;
		}
	}

	//输出b数组
	for (i = 0; i < cnt; i++) {
		printf("%c", s[i]);

	}
	printf("\n");

	return 0;
}

(写了俩周的题写出来还是有成就感的)

三.问题

1.回文字符

没有正确使用for循环,写的很乱,还不能正确运行

#include
int main(int argc,char* argv[])
{
	char s[50000];
	gets(s);
	int cnt=0,i=0,j,t=0;
	int b = 0;
	while (s[i] != '\0') {
		i++;
		cnt++;
	}
	printf("%d\n", cnt);
	if (cnt % 2 == 0) {
		for (i = 0; i < cnt / 2; i++) {
			for (j = (cnt-1) ; j > ((cnt / 2)-1); j--) {
				//printf("%c,%c\t", s[i], s[j]);
				if (s[i] == s[j]) {
					t++;
				}
				if (t == (cnt / 2))
				{
					b = 1;
				}
			}
		}
	}
	else {
		for (i = 0; i < cnt / 2; i++) {
			for (j = (cnt - 1); j > (cnt / 2) ; j--) {
				//printf("%c,%c\t", s[i], s[j]);
				if (s[i] == s[j]) {
					t++;
				}
				if (t == cnt / 2)
				{
					b = 1;
				}
			}
		}
	}

	if (b == 1) {
		printf("true");
	}
	else {
		printf("false");
	}
	return 0;
}

2.输出月份英文名

#include 
#include
char* getmonth(int n) {
    switch (n) {
    case 1: return "January";
    case 2: return "February";
    case 3: return "March";
    case 4: return "April";
    case 5: return "May";
    case 6: return "June";
    case 7: return "July";
    case 8: return "August";
    case 9: return "September";
    case 10: return "October";
    case 11: return "November";
    case 12:return "December";
    default: return NULL;
    }
}

int main015()
{
    int n;
    char* s;
    char* b;
    scanf_s("%d", &n);
 
    b = getmonth(n);
    if (s == NULL) printf("wrong input!\n");
    else printf("%s\n", s);
    printf("%s", b);
    return 0;
}

这个是运行正确的,我想用strcpy函数将每个月份的英文拷贝到一个字符串数组中,并利用swtich-case输出,还在尝试中没写出来

你可能感兴趣的:(visual,studio,c语言)