2023最新C语言基础快速入门自学笔记(温故而知新) C关键字、指针、结构体、常用函数、常用经典算法

0.0.仅供学习参考,如有侵权请联系删除,谢谢!

一、extern声明

不同文件下 使用同一变量或函数
在这里插入图片描述

二、sizeof运算符

//可以方便算出数组中元素的个数
// sizeof(字符串),'\0'也算字符数!!!
int array[10] = {0};
int count = sizeof(array) / sizeof(array[0]);
int count1 = sizeof(array) / sizeof(int);
// 结果为 count = count1 = 10
printf("sizeof('a')=%d sizeof(\"a\")=%d\n", sizeof('a'), sizeof("a"));
//‘a’是int类型,所以输出4 ;“a”才是char类型,所以输出2(1*2字符串结尾的\0)

三、关键字

3.1 register (寄存器建议)

register int num = 100; // 建议将num放到寄存器,但放不放还是编译器说了算

3.2 typedef (重定义)

typedef unsigned int u_int; //重定义 即将 u_int 作为 unsigned int 的别名使用

3.3 static (静态修饰)

3.31 修饰局部变量

在函数内加了static后(成为全局变量了),a的生命周期变长(本质是改变了存储类型);
a在出了addOne() 后也不会被销毁,而是会被a++的值替代

void addOne()
{
	static int a=0;
	a++;
	printf("%d ",a);	
	//a在被static修饰时输出 1 2 3 4 5 ... 10
	//未修饰时输出 1 1 1 ... 1 1
}
int main(){
	int i=0;
	while(i<10)
	{
		addOne();
		i++
	}
	return 0;
}

3.32 修饰全局变量

其他源文件将无法引用被static修饰的变量!!

3.4 define

#define ADD(X,Y) X+Y
#define NEWADD(X,Y) ((X)+(Y))

int main()
{
	printf("%d\n",4*ADD(2,3));
	//			  4*2+3
	printf("%d\n",4*NEWADD(2,3));
	//			  4*(2+3)
	return 0;
}

四、常用函数

4.1 strlen(字符串名)

计算字符串的长度

4.2 strcmp(s1,s2)

s1==s2时返回0,s1>s2时返回正整数,s1<s2时返回负整数;s2可直接为“123456”

4.3 system(“cls”)

清空屏幕

五、 指针与结构体

5.1 指针

5.11 首次见面

int main()
{
	int num = 10;
	int *p = &num;
	*p = 20;
	return 0;
}

初级指针-13

5.12 初级阶段

1.指针类型
int main()
{
	//指针类型决定了:1.指针解引用的能用的字节有多少 2.指针+1能加多少字节
	int x[] = { 10 };
	int	*p = &x;	// "*"贴着变量名的好处是更易于区分eg: int *p , a;
	char *pc = &x;
	
	printf("%p\n", p);
	printf("%p\n", p+1); //通过打印内存即可看出指针类型不同而带来的不同
	printf("%p\n", pc);
	printf("%p\n", pc+1);

	return 0;
}
2.野指针

简单来讲就是指针指向了未知的、未分配的内存地址

//(1)指针未初始化
	int *p;
	*p = 99;					//error!! 应该在定义时就初始化
		
//(2)将未知地址赋给指针
	int x[10] = { 10 };
	int	*p = &x;
	int i = 0;
	for (i = 0; i < 11; i++)	//error!!! 数组大小明明只有10,但你偏要搞第11个
	{
		*p = i;
		p++;
	}

//(3)将已经归还的内存地址赋给指针
	int *Chuo()
	{
		int x = 1;
		return &x;
	}
	int main()
	{	
		int *p = Chuo();
		*p = 88;			//error!!! 在Chuo()调用完后,x销毁了;地址已经还给操作系统,用户已经没有权限去设置了
		return 0;
	}

//(4)引用空指针
	int *p = NULL;
	printf("%d\n", *p);		//error!!! null可以先理解为0,用户没有控制“0”地址的权限

5.2 结构体

//创建一个学生
struct Stu
{
	char name[20];
	int id;
	int age;
};

int main()
{
	//结构体的创建和初始化
	struct Stu s1 = { "张大帅",20230188,23};
	
	//与指针初步结合
	struct Stu *ps1 = &s1;
	
	printf("1.%s %d %d\n", s1.name, s1.id, s1.age);
	printf("2.%s %d %d\n", (*ps1).name, (*ps1).id, (*ps1).age);
	printf("3.%s %d %d\n", ps1->name, ps1->id, ps1->age);
	return 0;
}

六、必备基础算法(内容太多,得单独出才行了)

6.1 求阶乘之和

int main()
{
	int i, j, sum = 0, x;
	scanf("%d", &x);
	for (i = 1; i <= x; i++)
	{
		//每次将 n 归 1 才是正常算阶乘,否则就会把循环前的数给拉下了
		//即1*2 1*2*3 1*2*3*4
		int n = 1;
		for (j = 1; j <= i; j++) {
			n = n * j;
		}
		sum += n;
	}
	printf("1 - %d 的阶乘之和为 %d\n", x, sum);
	return 0;
}

6.2 二分查找

int main() 
{
	int arr[] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20 };	//被查找的数组必须是有序数组
	
	int findX = 188;	//需要被找的数
	
	int len = sizeof(arr) / sizeof(arr[0]); //计算数组元素个数

	int left = 0;
	int right = len - 1;

	while (left <= right) //左界与右界中还有数字,包括他们自身也是要比较的
	{
		int mid = (left + right) / 2;
		if (arr[mid] < findX) //中间数比要找的数小,将左界往右边移
		{
			left = mid + 1;
		}
		else if (arr[mid] > findX) //中间数比要找的数大,将右界往左边移
		{
			right = mid - 1;
		}
		else
		{
			printf("找到了\n");
			break;
		}
	}
	if (left > right) 
	{
		printf("没找到\n");
	}
	return 0;
}

从两边向中心显示

int main() {

	char s1[] = "!!!aaaaaaaaaaaaaaa!!!";
	char s2[] = "*********************";
	int len = strlen(s1);//计算字符串长度

	int left = 0;
	int right = len - 1;

	int timer = 0;
	while (timer<=len/2) {
		s2[left] = s1[left];
		s2[right] = s1[right];
		left++;
		right--;
		printf("%s\n", s2);
		timer++;
	}
	
	return 0;
}

6.3 随机数

#include <stdlib.h>
#include <Time.h>
int main(){
	srand((unsigned int) time(NULL));//控制rand的
	int num=rand() % 100 + 1 ;//控制随机数范围为1-100
return 0;
}

6.4 闰年条件

((year % 4 == 0)&&(year % 100 != 0)) || (year % 400 == 0)

6.5 冒泡排序

int main()
{
	int sz[] = { 0,5,9,8,1,3,2,6,7,9,8,2 };
	int len = sizeof(sz) / sizeof(sz[0]);
	//数组元素个数
	//如果待排序数要从键盘输入,那必须先知道总个数
	int i;
	int j;
	int temp = 0;
    //如果有n个数,就只需n-1次循环就能排完序
	for (i = 0; i < len - 1; i++) 
	{
		for (j = 0; j < len - 1 - i; j++)
		{
			if (sz[j] > sz[j + 1])
			{
				temp = sz[j];
				sz[j] = sz[j + 1];
				sz[j + 1] = temp;
			}
		}
	}
	for (i = 0; i < len - 1; i++) {
		printf("%d ", sz[i]);
	}

	return 0;
}

6.6 最大公约数、最小公倍数

int main() 
{
	int a = 6;
	int b = 15;
	int i = 1;

	scanf("%d %d", &a, &b);

	if (b < a) //确保 b 最大
 {
		int t = b;
		b = a;
		a = t;
	}

	//公约数
	for (i = a; i > 0; i--)
	{
		if ( (a % i == 0) && (b % i == 0))
		{
			printf("最大公约数:%d\n", i);
			break;
		}
	}

	//公倍数
	if (b % a == 0)
	{
		printf("最小公倍数:%d\n", b);
	}
	else
	{
		int j = 0;
		while (1)
		{
			j++;
			if ((b + j) % a == 0 && (b + j) % b == 0)
			{
				break;
			}
		}
		printf("最小公倍数:%d\n", b + j);
	}
	
	return 0;
}

七、遗忘的知识点

7.1 导入静态库

#pragma comment(lib,"xxx.lib")
//有头文件和静态库(.lib)时导入
//作用:.lib文件就是将.c文件转换成二进制了

7.2 数组名

// 一般来讲 数组名就是数组的首元素地址
// 不一般来讲 1. sizeof(数组名) 此时“数组名”代表整个数组,计算的是整个数组的大小,单位字节
//           2. &数组名 此时“数组名”代表整个数组,取出的是整个数组的地址;如果将其+1,那就是下一个“数组”的“整个数组”
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值