c语言代码

目录

1.利用goto的关机程序

2.交换两个整数(容易出现的错误)

[2.1 错误示范](#2.1 错误示范)

[2.1.1 错误的原因](#2.1.1 错误的原因)

3.函数调用进行折半查找

3.1错误版本

3.1.1错误原因

4.写一个函数,每调用一次这个函数,就会将num的值增加1。

4.1使用传值进去

5.有关print的操作题

6.字符串比较

7.编写函数不允许创建临时变量,求字符串的长度。

7.1创建count变量来实现代码

[7.2 利用递归来正确实现代码](#7.2 利用递归来正确实现代码)

8.求第n个斐波那契数。(不考虑溢出)

[8.1 利用递归(效率很慢)](#8.1 利用递归(效率很慢))

[8.2 利用循环(不考虑栈溢出,因为这里输入小一点的数正确,大一点就会栈溢出,结果错误,但是效率很快)](#8.2 利用循环(不考虑栈溢出,因为这里输入小一点的数正确,大一点就会栈溢出,结果错误,但是效率很快))

9.冒泡排序

1.利用goto的关机程序

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
//#inculde<string.h>  部分版本需要引用这个头文件
#include<stdio.h>
int main() {
	system("shutdown - s - t 60");
	char arr[20] = { 0 };
flag:
	printf("电脑在1分钟内关机,请输入我是猪来取消关机!");
	scanf("%s", arr);
	if (strcmp(arr, "我是猪") == 0) {
		system("shutdown -a");
	}
	else {
		goto flag;
	}
	return 0;
}

上述代码简单修改,利用while循环来实现关机.

cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
//#inculde<string.h>
#include<stdio.h>
int main() {
	system("shutdown - s - t 60");
	char arr[20] = { 0 };
	while (1) {
		printf("电脑在1分钟内关机,请输入我是猪来取消关机!");
		scanf("%s", arr);
		if (strcmp(arr, "我是猪") == 0) {
			system("shutdown -a");
			break;
		}
	}
	return 0;
}

!!!! goto语句只能在一个函数范围内跳转,不能跨函数

2.交换两个整数(容易出现的错误)

2.1 错误示范
cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
//#inculde<string.h>
#include<stdio.h>
int swap(int x, int y) {
	int z = 0;
	z = x;
	x = y;
	y = z;
}
int main() {
	int a = 10;
	int b = 20;
	printf("交换前:a=%d b=%d\n", a, b);
	swap(a, b);
	printf("交换后:a=%d b=%d\n", a, b);
	return 0;
}
2.1.1 错误的原因

之所以出现错误是因为函数传参的过程中,a b本身是有地址空间的,但是x y也开辟了地址空间,这就导致他们的地址空间并不一样!

这里相当于给x y开辟了空间,x中放的是10,y中放的是20.然后z也开辟了空间,在执行swap函数中,尽管x y实现了互换,但是根本没有影响a b的值,跟a b都不是一个空间的地址。所以导致了a b的值没有实现互换!

2.1.2 修改正确的版本(利用指针)

举例

cpp 复制代码
#include<stdio.h>
int main() {
	int a = 10;//4个字节的空间
	int* pa = &a;//pa就是一个指针变量
	*pa = 20;
	printf("%d\n", *pa);
	printf("%d", a);
	return 0;
}

正确版本

cpp 复制代码
#include<stdio.h>
void swap(int *pa, int *pb) {//void 不用写返回,也可以直接写人return;
	int z = *pa;
	*pa = *pb;
	*pb = z;
}
	int main() {
	int a = 10;
	int b = 20;
	printf("交换前:a=%d b=%d\n", a, b);
	swap(&a, &b);//传入地址
	printf("交换后:a=%d b=%d\n", a, b);
	return 0;
}

3.函数调用进行折半查找

cpp 复制代码
#include<stdio.h>
	int	binary_search(int a[], int k, int s) {
		int left = 0;
		int right = s - 1;
		while (left <= right) {
			int mid = (left + right) / 2;
			if (a[mid] > k) {
				right = mid - 1;
			}
			else if (a[mid] < k) {
				left = mid + 1;
			}
			else {
				return mid;
			}
		}
		return -1;
	}

	int main(){
		int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
		int key = 7;
		int sz = sizeof(arr) / sizeof(arr[0]);
		int ret = binary_search(arr,key,sz);
		if (-1 == ret) {
			printf("找不到\n");
		}
		else {
			printf("找到了,下标是:%d\n",ret);
		}
	return 0;
}
3.1错误版本
cpp 复制代码
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
	int	binary_search(int a[], int k) {
		int sz = sizeof(a) / sizeof(a[0]);//求数组个数,错误
		int left = 0;
		int right = sz - 1;
		while (left <= right) {
			int mid = (left + right) / 2;
			if (a[mid] > k) {
				right = mid - 1;
			}
			else if (a[mid] < k) {
				left = mid + 1;
			}
			else {
				return mid;
			}
		}
		return -1;
	}

	int main(){
		int arr[] = { 1,2,3,4,5,6,7,8,9,10 };
		int key = 7;
		
		int ret = binary_search(arr,key);//不传sz,错误
		if (-1 == ret) {
			printf("找不到\n");
		}
		else {
			printf("找到了,下标是:%d\n",ret);
		}
	return 0;
}
3.1.1错误原因

数组arr传参,实际传递的不是数组的本身,仅仅传过去了数组首元素的地址

实际上 int binary_search(int a[], int k)就等于 int binary_search(int *a, int k);int a[ ]就是挂羊头卖狗肉,实际上就是个指针,因此int sz = sizeof(a) / sizeof(a[0]);求得的sz就是4/4=1;再往下进行代码计算就肯定不对了**!**

而在int binary_search(int a[], int k)中int a[ ]中没写大小,如int a[10]是因为数组都没传过来,这里创建一个数组也没意义!

!!!!!所以函数内部需要参数部分传过来数组的个数,一定是在外面求好这个数组个数在传过去,而不是在函数内部在去求!实际上数组传参就是一种传址的效果!

4.写一个函数,每调用一次这个函数,就会将num的值增加1。

cpp 复制代码
#include<stdio.h>	
void Add(int* p) {
	(*p)++;
}
int main() {
	int num = 0;
	Add(&num);
	printf("%d\n", num);

	Add(&num);
	printf("%d\n", num);

	Add(&num);
	printf("%d\n", num);
	return 0;
}

函数内部想改变函数外部,一般都采用传址操作!

4.1使用传值进去
cpp 复制代码
#include<stdio.h>	
int  Add(int p) {
	p++;
	return p;
}
int main() {
	int num = 0;
	int a=Add(num);
	printf("%d\n", a);

	int b = Add(num);
	printf("%d\n", b);

	int c = Add(num);
	printf("%d\n", c);
	return 0;
}

5.有关print的操作题

cpp 复制代码
#include<stdio.h>	
int main()
{
	printf("%d", printf("%d",printf("%d", 43)));
	return 0;
}

结果是4321;原因是因为print返回值类型为

函数返回的是打印在屏幕上的字符的个数

所以

6.字符串比较

字符串比较时,1.如

不能直接用 == ,这里需要引入头文件 #incolude<string.h>;然后使用strcmp进行对比;

而如果出现两个字符串比较,如str1="abcd",str2="abce",比较结果为<0,因为字符串比较,实际上比较的是ascii码值,比较的结果有3个为<0,>0,=0.

2.如果定义的是一个数组,那么在scanf中不用加&取地址符。因为对应的password就是数组名,数组名本身就是一个地址了。

3.

这里红色方框比较的是两个字符串的首字符的地址,并没有比较内容。地址比较是没有意义的!

7.编写函数不允许创建临时变量,求字符串的长度。

7.1创建count变量来实现代码
cpp 复制代码
#include<stdio.h>	
int my_strlen(char* str)//*str解引用得到值
{
	int count = 0;
	while (*str != '\0') {
		count++;
		str++;//str代表的数组下标,也就是字母的地址
	}
	return count;
}
int main()
{
	char arr[] = "cxs";
	//['c']['x']['s']['\0']
	//模拟实现一个strlen函数
	printf("%d\n",my_strlen(arr));//数组传参,传的是数组的首地址
	return 0;
}
7.2 利用递归来正确实现代码
cpp 复制代码
#include<stdio.h>	
int my_strlen(char* str)
{
	if(*str != '\0') {
		return 1 + my_strlen(str + 1);//也可以是str+1对应的是下一个字母的地址,然后在传给char *atr
	}
	else {
		return 0;
	}
}
int main()
{
	char arr[] = "cxs";
	//['c']['x']['s']['\0']
	//模拟实现一个strlen函数
	printf("%d\n",my_strlen(arr));//数组传参,传的是数组的首地址
	return 0;
}

8.求第n个斐波那契数。(不考虑溢出)

8.1 利用递归(效率很慢)
cs 复制代码
#include<stdio.h>	
int Fib(int n) {
	if (n <= 2) {
		return 1;
	}
	else {
		return Fib(n - 1) + Fib(n - 2);
	}
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = Fib(n);
	printf("%d\n", ret);
	return 0;
}
8.2 利用循环(不考虑栈溢出,因为这里输入小一点的数正确,大一点就会栈溢出,结果错误,但是效率很快)
cs 复制代码
#include<stdio.h>	
int Fib(int n) {
	int a = 1;
	int b = 1;
	int c = 1;//c赋值为1;是因为n<2时,直接返回c的值刚好是1!
	while (n > 2) {
		c = a + b;
		a = b;
		b = c;
		n--;
	}
	return c;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = Fib(n);
	printf("%d\n", ret);
	return 0;
}

9.数组部分

也会导致求长度不对

cs 复制代码
#include<stdio.h>
int main(){
	int arr[3][4] = { {1,2},{3,4},{5,6} };
	int i = 0;
	int j = 0;
	int a = arr[0][0];
	int* p = &arr[0][0];//这里可以看出p是指针,*p解引用是一个值,但是arr想要与指针比较,默认也是指针,需要&解引用
	for (i = 0; i < 3; i++) {
		for (j = 0; j < 4; j++) {
			printf("%d", *p);
			p++;
		}
	}
	printf("\n%d", a);
	return 0;
}

9.冒泡排序

cs 复制代码
#include<stdio.h>
void mao_pao(int a[], int k) {
	int i = 0;
	int temp;
	for (i; i < k - 1; i++) {//会比较9轮
		int j = 0;
		for (j; j < k - 1 - i; j++) {//每轮会比较的次数
			if (a[j] > a[j + 1]) {
				temp = a[j];
				a[j] = a[j + 1];
				a[j + 1] = temp;
			}
		}
	}
}
	int main() {
		int arr[] = { 9,8,7,6,5,4,3,2,1,0 };
		int len = sizeof(arr) / sizeof(arr[0]);
		mao_pao(arr, len);
		for (int i = 0; i < len; i++) {
			printf("%d", arr[i]);
		}
		return 0;
	}

10.数组名的不同

尽管我们看到三个的地址都一样,但是实际上2和3才是真正意义一样的,因为1虽然代表的是整个数组,但是他的地址也是从第一个元素开始,因此地址才和2 3一样!下面通过例子看看1和2 3 是不一样的!

可以看出,1中的&arr+1,因为是数组地址加1,50-28=28,但是是16进制,就是0x28换算十进制就是40,但是2中的arr+1,是数组首元地址加1,十进制是4。也就是说1中的&arr+1是整个数组地址加1,而2中的arr+1是首元地址+1.

相关推荐
懒大王爱吃狼35 分钟前
Python教程:python枚举类定义和使用
开发语言·前端·javascript·python·python基础·python编程·python书籍
劲夫学编程36 分钟前
leetcode:杨辉三角
算法·leetcode·职场和发展
毕竟秋山澪38 分钟前
孤岛的总面积(Dfs C#
算法·深度优先
秃头佛爷2 小时前
Python学习大纲总结及注意事项
开发语言·python·学习
待磨的钝刨2 小时前
【格式化查看JSON文件】coco的json文件内容都在一行如何按照json格式查看
开发语言·javascript·json
浮生如梦_3 小时前
Halcon基于laws纹理特征的SVM分类
图像处理·人工智能·算法·支持向量机·计算机视觉·分类·视觉检测
XiaoLeisj4 小时前
【JavaEE初阶 — 多线程】单例模式 & 指令重排序问题
java·开发语言·java-ee
励志成为嵌入式工程师5 小时前
c语言简单编程练习9
c语言·开发语言·算法·vim
捕鲸叉5 小时前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer5 小时前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法