c语言学习备忘

在visual studio2022里开发,兼容C++语法的。

1、visual studio 2022怎么写C语言

https://blog.youkuaiyun.com/m0_64589890/article/details/133894336

https://www.bilibili.com/video/BV1CA1vYoEyr/

2、switch的case不要break会怎么样

#include <stdio.h>
int main() {
	char grade;
	scanf_s("%c", &grade);
	printf("Your score:");
	switch (grade) {
		case 'A':
			printf("85~100\n");
			//break;
		case 'B':
			printf("70~84\n");
			//break;
		case 'C':
			printf("60~69\n");
			//break;
		case 'D':
			printf("<60\n");
			//break;
		default:
			printf("enter data error!\n");
	}
		
	return 0;
}

这种情况,输入B,会打印如下:

3、strcpy和strncpy的区别

3.1、strcpy会复制'\0'

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {

	char pinjie[5] = { 'a','b','f'};
	char beipinjie[] = { "cd" };
	strcpy(pinjie, beipinjie);
	printf("%s", pinjie);
	return 0;
}

运行结果如下图所示,不会打印f出来

3.2、strncpy不会复制'\0',只会复制指定数量的字符

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {

	char pinjie[5] = { 'a','b','f'};
	char beipinjie[] = { "cd" };
	strncpy(pinjie, beipinjie, 2);
	printf("%s", pinjie);
	return 0;
}

运行结果如下,会打印出cdf后面的f不会丢失,也会打印出来。

4、比较字符串大小

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
	printf("%d", strcmp("1A","$20"));
	return 0;
}

预期打印1,实际如下图所示:

如果是如下代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
	printf("%d", strcmp("1A","20"));
	return 0;
}

则打印-1

5、计算长度strlen

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
	char str[10] = "China";
	printf("%d", strlen(str));
	return 0;
}

不是10,也不是6,而是5,结果如下图所示:

6、字符数组使用例子

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main() {
	char string[81];
	int i, num = 0, word = 0;
	char c;
	gets(string);
	for (i = 0; (c = string[i]) != '\0'; i++)
		if (c == ' ')word = 0;
		else if (word == 0)
		{
			word = 1; num++;
		}

	printf("There are %d words in this line, \n", num);
	return 0;
}

运行结果如下:

7、函数的递归调用

第5个学生比第4个学生大2岁,第4个学生比第3个学生大2岁,依此类推,第2个学生比第1个学生大2岁。已知第1个学生10岁,求第5个学生的年龄。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>


int main()
{
	int age(int n); 
	printf("NO.5.age:%d\n",age(5));
	return 0;
}

int age(int n)
{
	int c;
	if (n == 1)
		c = 10;
	else
		c = age(n - 1) + 2;
	return(c);
}

运行结果如下图所示:

8、在同一个源文件中,全局变量与局部变量同名,这时会出现什么情况呢?请考虑是按哪一种情况处理:(1)出错;(2)局部变量无效,全局变量有效;(3)在局部变量的作用范围内,局部变量有效,全局变量被“屏蔽”,即它不起作用。请先分析下面的程序。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int a = 3, b = 5;
int main() 
{
	int max(int a, int b);
	int a = 8;
	printf("max=%d\n", max(a, b));
	return 0;
}
int max(int a,int b)
{
	int c;
	c = a > b ? a : b;
	return(c);
}

运行结果如下图所示:

分析如下:

9、跨文件调用方法和引用变量

FileName.c文件代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>


//定义外部变量
int A;
int main()
{
	int power(int);
	//函数声明
	int c,d,m;
	printf("enter the number a and its power m;\n" );
	scanf("%d,%d", &A, &m);
	c = A*m;
	printf("%dx%d=%d\n", A,  m, c);
	d = power(m);
	printf("%d**%d=%d\n", A, m, d);
	return 0;
}

file2.c文件代码如下:


extern A;
int power(int n)
{
	int i, y = 1; 
	for (i = 1; i <= n; i++)
	{
		//把在ile1文件中已定义的外部变量的作用域扩展到本文件
		y *= A;
	}
	return(y);
		
}

运行结果如下:

10、处理文件

10.1、将内容输出到文件中

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main()
{
	FILE* fp;
	//定义文件指针p
	char ch, filename[10];
	printf("请输人所用的文件名:");
	scanf(" %s", filename);
	getchar();
	if ((fp = fopen(filename, "w")) == NULL)
	{
		printf("cannot open file\n");
		exit(0);
	}
	//输入文件名
	//用来消化最后输入的回车符
	//打开输出文件并使印指向此文件
	//如果打开出错就输出“打不开”
	//终止程序
	printf("请输入一个准备存储到磁盘的字符串(以#结束):");
	//第10章 对文件的输入输出
	ch = getchar();
	while (ch != '#')
	{
		fputc(ch, fp);
		putchar(ch);
		ch = getchar();
	}
	fclose(fp);
	putchar(10);
	//接收从键盘输人的第一个字符
	//当输人'#'时结束循环
	//向磁盘文件输出一个字符
	//将输出的字符显示在屏幕上
	//再接收从键盘输入的一个字符
	//关闭文件
	//向屏幕输出一个换行符
	return 0;
}

运行结果如下:

同目录下生成了a.txt,文件内容如下:

10.2、将一个文件中的内容复制到另外的文件中。代码如下所示:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main()
{
	FILE* in,*out;
	//定义文件指针p
	char ch, infile[10],outfile[10];
	printf("请输入所用的输入文件名:");
	scanf(" %s", infile);
	printf("请输入所用的输出文件名:");
	scanf(" %s", outfile);
	getchar();
	if ((in = fopen(infile, "r")) == NULL)
	{
		printf("cannot open file\n");
		exit(0);
	}
	if ((out = fopen(outfile, "w")) == NULL)
	{
		printf("cannot open file\n");
		exit(0);
	}
	//输入文件名
	//用来消化最后输入的回车符
	//打开输出文件并使印指向此文件
	//如果打开出错就输出“打不开”
	//终止程序
	printf("请输入一个准备存储到磁盘的字符串(以#结束):");
	//第10章 对文件的输入输出
	ch = fgetc(in);
	while (!feof(in))
	{
		fputc(ch, out);
		putchar(ch);
		ch = fgetc(in);
	}
	putchar(10);
	fclose(in);
	fclose(out);
	//接收从键盘输人的第一个字符
	//当输人'#'时结束循环
	//向磁盘文件输出一个字符
	//将输出的字符显示在屏幕上
	//再接收从键盘输入的一个字符
	//关闭文件
	//向屏幕输出一个换行符
	return 0;
}

达到预期了。

while语句换成while (ch!=EOF)或者while (ch!=-1)都可以。

11、指针

11.1、改变指针指向的值

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main()
{
	int a = 2, b = 3;
	int* p1, * p2, * p;
	p1 = &a;
	p2 = &b;
	if (a < b)
	{
		p = p1;
		p1 = p2;
		p2 = p;
	}
	printf("a=%d,b=%d\n", a, b);
	printf("max=%d,min=%d\n", *p1, *p2);
	
	return 0;
}

运行效果如下图所示:a和b的值并没有改变。

11.2、改变指针指向的变量的值

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main()
{
	void swap(int* pp1, int* pp2);
	int a = 2, b = 3;
	int* p1, * p2, * p;
	p1 = &a;
	p2 = &b;
	if (a < b)
	{
		swap(p1, p2);
	}
	printf("a=%d,b=%d\n", a, b);
	printf("max=%d,min=%d\n", *p1, *p2);
	
	return 0;
}

void swap(int* pp1, int* pp2)
{
	int temp = *pp1;
	*pp1 = *pp2;
	*pp2 = temp;
}

运行效果如下图所示:a和b的值都对应改变了。

11.3、期望改变a和b的值,但实际没有改变a和b的值。

代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main()
{
	void swap(int* pp1, int* pp2);
	int a = 2, b = 3;
	int* p1, * p2, * p;
	p1 = &a;
	p2 = &b;
	if (a < b)
	{
		swap(p1, p2);
	}
	printf("a=%d,b=%d\n", a, b);
	printf("max=%d,min=%d\n", *p1, *p2);
	
	return 0;
}

void swap(int* pp1, int* pp2)
{
	int *temp = pp1;
	pp1 = pp2;
	pp2 = temp;
}

运行结果如下:

12、用指针指向数组。

12.1、通过数组名计算数组元素地址,找出元素的值

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main()
{
	int a[10];
	int i;
	printf("please enter 10 integer numbers:");
	for (i = 0; i < 10; i++) {
		scanf("%d", &a[i]);// 换成scanf("%d", a+i);也行。
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d ", *(a + i));
	}
	printf("\n");
	//通过数组名和元素序号计算元素地址,再找到该元素
	return 0;
}

运行结果如下:

12.2、用指针变量指向数组元素

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main()
{
	int a[10];
	int *p,i;
	printf("please enter 10 integer numbers:");
	for (i = 0; i < 10; i++) {
		scanf("%d", a+i);
	}
	for (p=a; p < a+10; p++)
	{
		printf("%d ", *p);
	}
	printf("\n");
	//通过数组名和元素序号计算元素地址,再找到该元素
	return 0;
}

运行结果如下图所示:

12.3、同一个指针变量,循环二次,会出问题。

代码如下:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main()
{
	int a[10];
	int *p,i;
	p = a;
	printf("please enter 10 integer numbers:");
	for (i = 0; i < 10; i++) {
		scanf("%d", p++);
	}
	for (i=0; i < 10; p++,i++)
	{
		printf("%d ", *p);
	}
	printf("\n");
	//通过数组名和元素序号计算元素地址,再找到该元素
	return 0;
}

运行结果如下:

在第二个for之前加上p=a;就行了。

12.4、*p++和*++p的区别。

*p++,是先取*p的值,再给p++。等价于*(p++)

代码如下所示:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
int main()
{
	int a[10];
	int *p,i;
	p = a;
	printf("please enter 10 integer numbers:");
	for (i = 0; i < 10; i++) {
		scanf("%d", p++);
	}
	p = a;
	for (i=0; i < 10; i++)
	{
		printf("%d ", *p++);
	}
	printf("\n");
	return 0;
}

运行结果符合预期:

而如果换成了*++p,就会先取a[1]而不是a[0],那第10轮的时候就会取到无法想象的值了。等价于*(++p)。

代码和运行结果如下图所示:

还有一种写法,++(*p);是指*p指向的数组元素其值加1

代码和运行结果如下图所示:

12.5、数组有10个数,交换数组元素的位置,将第1个数和最后一个数交换位置,第2个数和倒数第2个数交换位置,依此类推。

例如

思路如图所示:

12.5.1、实参和形参都使用数组,代码如下所示:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	void inv(int x[], int n);
	int i, a[10] = { 3,7,9,11,0,6,7,5,4,2 };
	printf("The original array:\n");
	for (i = 0; i < 10; i++)
		printf("%d ", a[i]);
	printf("\n");
	inv(a,10);
	printf("The array has been inverted,\n");
	for (i = 0; i < 10; i++)
		printf("%d ", a[i]);
	printf("\n");
	return 0;
}

void inv(int x[], int n)
{
	int temp,i,j,m = (n - 1) / 2; 
	for (i = 0; i <= m; i++)
	{
		j = n - 1 - i;
		temp = x[i];
		x[i] = x[j];
		x[j] = temp;
	}
}

运行结果如下图所示:

12.5.1、实参使用数组,形参使用指针,代码如下所示:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
	void inv(int x[], int n);
	int i, a[10] = { 3,7,9,11,0,6,7,5,4,2 };
	printf("The original array:\n");
	for (i = 0; i < 10; i++)
		printf("%d ", a[i]);
	printf("\n");
	inv(a,10);
	printf("The array has been inverted,\n");
	for (i = 0; i < 10; i++)
		printf("%d ", a[i]);
	printf("\n");
	return 0;
}

void inv(int* x, int n)
{
	int* p, temp, * i, * j, m = (n - 1) / 2;
	i = x; j = x + n - 1;
	p = x + m;
	for (; i <= p; i++, j--)
	{
		temp = *i;
		*i = *j;
		*j = temp;
	}
	return;
}

运行结果如下图所示:

如果数组改成9个元素,代码和运行结果如下图所示:

实际结果符合期望。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值