C语言基础

感谢大家的关注和支持,一起进步,一起加油!

  • 前言
    • 环境安装
    • 基础语法
    • 运算符
    • 程序流程结构
    • 一维数组
    • 二维数组
    • 结构体
    • 指针
    • 函数
    • 文件
  • 小结

前言

  • 功能强大
    • 操作系统、嵌入式、动态库、服务器、应用程序、外挂、其他语言等
  • 执行效率高
    • C语言描述问题比汇编语言简练,而代码质量与汇编语言相当
  • 可移植性好
    • 一个环境上用C语言编写的程序,不改动或稍加改动,就可移植到另一个完全不同的环境中运行

环境安装

vs code

基础语法

#pragma warning(disable:4996)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

#define A 100

void test01() {
	// 数据类型 注意数据范围,溢出问题
	//sizeof 248
	short n1 = 10;
	int n2 = 10;
	long n3 = 10;
	long long n4 = 10;

	printf("n1=%hd,占用内存:%d  %d\n", n1, sizeof(short),sizeof(n1));
	printf("n2=%d\n", n2);
	printf("n3=%ld\n", n3);
	printf("n4=%lld\n", n4);
}

void test02() {
	// 字符型
	// sizeof 1
	// a--97   A--65  0--48
	char ch = 'a';
	char ch1 = 'A';
	printf("ch=%c--%d\n", ch, sizeof(ch));

}

void test03() {
	// 字符串
	// 1. 单精度float 占4字节, 7位有效数字
	// 2. 双精度doubl 占8字节, 15-16位有效数字
	printf("sizeof = %d\n", sizeof(3.14)); //默认认为小数是double数据类型 8
	printf("sizeof = %d\n", sizeof(3.14f)); //加入f后 变为float数据类型   4
	printf("%f\n", 3.14); //默认显示小数点后6位   3.140000
	printf("%.2f\n", 3.14); //默认显示小数点后2位 3.14
 
}


void test04() {
	//双引号引起的内容 称为字符串常量
	printf("%s\n", "hello world"); // 双引号引起的内容中会带着字符串结束标志 \0

	//双引号会返回字符串的首字符的地址编号
	//%s输出时 遇到\0 结束输出 \0占一个字节
	printf("sizeof = %d\n", sizeof("hello world"));


	// 字符串变量
	char str[] = "hello world";
	printf("%s\n", str);
	printf("sizeof = %d\n", sizeof(str));
	str[0] = 'x';
	printf("%s\n", str);
}

void test05() {
	// 整型输入
	printf("请输入数据>>>\n");
	int num = 0;
	scanf("%d\n", &num);
	printf("num = %d", num);

	getchar(); //从缓存区中取走一个字符
	printf("请输入数据>>>\n");
	char ch1 = 'a';
	scanf("%c\n", &ch1);
	printf("num = %d", ch1);
	getchar(); //从缓存区中取走一个字符

	double d = 0;
	printf("请重新给d赋值\n");
	scanf("%lf", &d);
	printf("d = %.2lf\n", d);
	getchar(); //从缓存区中取走一个字符

	char ch[64] = "";
	printf("请重新给ch赋值\n");
	scanf("%s", ch);
	printf("ch = %s\n", ch);


}

int main() {
	// 变量,先定义后使用
	int a = 10;
	printf("a=%d\n", a);
	a = 100;
	printf("a=%d\n", a);
	//常量,不可以被修改
	//宏常量 #define
	//变量修饰的常量 const修饰
	printf("A=%d\n", A);
	const int c =  12;
	printf("c=%d\n", c);
	//标识符
	// 不能是关键字,区分大小写,不能由数字开头,以下划线,字母,数字组成


	// 数据类型
	test01();


	// 字符型
	test02();

	// 浮点型
	test03();


	// 字符串
	test04();
	


	//数据的输入
	//语法:scanf("格式化占位符", 输入数据地址);
	test05();

	system("pause");
	return 0;

 }


运算符

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

test() {
	// 算术运算符
	//只有整型变量可以进行取模运算
	// 0不可以做除数
	//++或者-- 在独立语句中没有区别
	int a = 10;
	int b = 3;
	printf("a + b = %d \n", a + b);
	printf("a - b = %d \n", a - b);
	printf("a * b = %d \n", a * b);
	printf("a / b = %d \n", a / b);
	printf("a %% b = %d \n", a % b);
	a++;
	printf("  %d \n", a);

}


void test01() {
	// 赋值运算符
	// 等号左边为左值,右边的为右值,看成一个整体
	int x = 3;
	x += 1;
	printf("x = %d \n", x);
	x -= 1;
	printf("x = %d \n", x);
	x *= 2;
	printf("x = %d \n", x);
	x /= 2;
	printf("x = %d \n", x);
	x %= 2;
	printf("x = %d \n", x);
}



void test03() {
	// 比较运算符
	// 0 为假
	// 1 为真
	int a = 1;
	int b = 3;
	printf("a == b 为%d \n", a == b);  //0
	printf("a >= b 为%d \n", a >= b);  //0
	printf("a <= b 为%d \n", a <= b);  //1
	printf("a != b 为%d \n", a != b);  //1
	printf("a > b  为%d \n", a > b);   //0
	printf("a < b  为%d \n", a < b);   //1

}

// 逻辑运算符

void test04() {
	int a = 10;
	printf("!a = %d\n", !a); //0
	printf("!!a = %d\n", !!a); //1
	int b = 0;
	printf(" a && b = %d\n", a && b); //1
	printf("a || b = %d\n", a || b); // 1
	 
}

// 优先级
void test05() {
	int a = 10;
	//自增自减运算符 优先级高于 * /
	printf("%d\n", ++a * 10); // 110

	//比较运算符 高于 赋值运算符
 	printf("%d\n", a = 23 > 24); // 0

	// 逻辑与 高于 逻辑或
	printf("%d\n", 1 || 1 && !0); //1

	//同一个级别 赋值运算 从右向左结合
	//a += a -= a *= a /= 3;
	printf("a = %d\n", a); //0

	int num = 0;
	num = 1, 2, 3, 4; //先赋值
	printf("num = %d\n", num); //1
	num = (1, 2, 3, 4,66); //1 2 3 4 66 先看结合性 让4 赋值给num
	printf("num = %d\n", num); //66
}

// 主函数
void main() {

	// 算术运算符
	test();

	// 赋值运算符
	test01();

	// 比较运算符
	test03();

	// 逻辑运算符
	test04();

	// 运算符优先级
	test05();



	system("pause");
	return 0;
}

程序流程结构

#pragma warning(disable:4996)
#include<stdio.h>
#include<stdlib.h>



// 分支
void test01() {
	//如果输入的数据 大于600分,认为考试一本大学,进行输出
	int score = 0;
	printf("请输入一个分数:\n");
	scanf("%d", &score);
	printf("您输入的分数为:%d\n", score);
	//语法: if(满足条件){ 满足条件成立,执行的语句 }
	if (score > 600)
	{
		printf("考上了重点大学!\n");
	}
	else if (score > 500) {
		printf("考上了一本大学!\n");

	}
	else
	{
		printf("没有考上本科!\n");
	}
}

// 循环
void test02() {
	int num = 0;
	while (num < 10)
	{
		printf("num = %d\n", num);
		//循环必须得有一个退出的条件,否则会进入死循环
		num++;
	}

}

//多条件 // 没有break会一直往下执行
void test03() {
	//给电影评分
	//10 ~ 9 经典
	//8 ~ 7 非常好
	//6 ~ 5 一般
	//5以下 烂片
	int score = 0;
	printf("请给电影打分:\n");
	scanf("%d", &score);
	printf("您给的分数是:%d\n", score);
	switch (score) //switch中的表达式类型,只能是整型或者字符型
	{
	case 10:
		//printf("经典\n");
		//break; //利用break结束分支
	case 9:
		printf("经典\n");
		break;
	case 8:
		//printf("非常好\n");
	//break;
	case 7:
		printf("非常好\n");
		break;
	case 6:
		//printf("一般\n");
		//break;
	case 5:
		printf("一般\n");
		break;
	default: //默认的分支
		printf("烂片\n");
		break;
	}
}
// 三目运算
void test04() {
	// 语法: 表达式1 ? 表达式2 :表达式3
	int a = 1;
	int b = 2;
	int c = 3;
	printf("res = %d \n", !a ? b : c);

}
// for
void test05() {
	//语法: for(起始表达式;条件表达式;末尾循环体) { 循环语句;}
	for (int i = 10; i > 0; i--) {
		printf("i= %d \n", i);
	}

}
// 正方形10x10
void test06() {
	int i = 0;
	while (i < 10) {
		for (int j = 0; j < 10; j++) {
			printf("* ");
		};
		printf("\n");
		i++;
	}
  }
// 乘法口诀
void test07() {
	// 行
	for (int j = 1; j < 10; j++) { 	
		for (int i = 1; i <= j; i++) {
			printf("j * i = %d  ",j*i);
		}
		printf("\n");
	}
}

//goto 无条件跳转语句
//由于容易让程序混乱,不建议用
void test08()
{
	printf("1\n");
	printf("2\n");
	goto FALG;
	printf("3\n");
	printf("4\n");
FALG:
	printf("5\n");
	printf("6\n");
}

test09() {
	int num = 0;
	do
	{
		printf("num = %d\n", num);
		num++;
	} while (num > 10);
}
// 主函数
void main(){
	test01();//分支
	test02();//while循环
	test03();//switch
	test04();//三目运算
	test05();//for循环
	test06();//10x10
	test07();//乘法表
	test08();//goto
	test09();//do-while
	// break 和continue 配合循环和switch

}

一维数组

#pragma warning(disable:4996)
#include<stdio.h>
#include<stdlib.h>


//数组
void test01() {
	/*
	一维数组定义的三种方式:
	1. 数据类型 数组名[ 数组长度 ];
	2. 数据类型 数组名[ 数组长度 ] = { 值1,值2 ...};
	3. 数据类型 数组名[ ] = { 值1,值2 ...};
	*/
 
	int score[10]; // 数组名 score , 数组中存放最多10个数据,每个数据的数据类型int
	//给数组元素赋值
	//从0开始索引位置
	score[0] = 100;
	score[1] = 99;
	score[2] = 98;
	//score[10] = 100; //下标越界
	//利用下标法输出
	printf("%d\n", score[0]);
	printf("%d\n", score[1]);
	printf("%d\n", score[2]);

	//int score2[10] = { 0,1, 2, 3, 4, 5, 6, 7, 8, 9 };
	//int score2[10] = { 0, 1, 2, 3, 4, 5}; //不足的10个数据,剩余的位置用0填充
	int score2[10] = { [1] = 10 , [5] = 50 , [7] = 70}; //部分初始化
	for (int i = 0; i < 10; i++)
	{
	 printf("%d\n", score2[i]);
	}

	int score3[] = { 1, 2, 3, 4, 5 ,6,7,8 };
	for (int i = 0; i < 8; i++)
	{
		printf("%d\n", score3[i]);
	}
}

// 一维数组的内存大小和首地址就是数组名
void test02() {
	int arr[10] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	//1、统计整个数组占用内存空间大小
	printf("sizeof arr = %d\n", sizeof(arr));
	printf("每个数据占用空间大小 = %d\n", sizeof(arr[0]));
	printf("数组中元素的个数 = %d\n", sizeof(arr) / sizeof(int));
	//2、通过数组的名称,获取到数组的首地址
	printf("数组的首地址为:%d\n", arr); //%p可以用十六进制显示 %d用十进制显示地址
	//printf("数组的首地址为:%p\n", arr);
	printf("数组中第一个元素的地址:%d\n", &arr[0]);
	printf("数组中第二个元素的地址:%d\n", &arr[1]);
	printf("数组中第三个元素的地址:%d\n", &arr[2]);
	//数组名常量,不可以赋值
	//arr = 100; error不可以给数组名赋值

	

}
// 最大值
void test03() {
	int arr[5] = { 0 };

	for (int i = 0; i < 5; i++)
	{
		scanf("%d", &arr[i]);

	}
	//在数组中找到最大值
	int max = 0; //认定第一个数就是最大值 ,记录下标
	int num = sizeof(arr) / sizeof(int); //数组元素个数
	for (int i = 1; i < num; i++)
	{
		if (arr[i] > arr[max]) //说明遍历的下标的元素更大
		{
			max = i;
		}
	}
	printf("最大的是%d 号 最大为:%d\n", max + 1, arr[max]);

}

// 数组倒置
void test04() {
	int arr[6] = { 1,3,5,2,4,6 };
	printf("逆置前的遍历结果为:\n");
	for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	//逆置
	int start = 0; //起始交换下标
	int end = sizeof(arr) / sizeof(int) - 1; //最后一个元素的下标
	while (start < end)
	{
		//创建临时遍历
		int temp = arr[start];
		arr[start] = arr[end];
		arr[end] = temp;
		//下标更新
		start++;
		end--;
	}
	printf("逆置后的遍历结果为:\n");
	for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");




}
void test05() {
	// 比较两个数组,前面比后面大就交换
	int arr[] = { 4,2,8,0,5,7,1,3,9 };
	for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
	//外层循环
	for (int i = 0; i < sizeof(arr) / sizeof(int) - 1; i++)
	{
		//内层循环
		for (int j = 0; j < sizeof(arr) / sizeof(int) - i - 1; j++)
		{
			// 如果第一个数字 比第二个数字大 交换代码
			if (arr[j] > arr[j + 1])
			{
				int temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
	for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");

	

}





void main() {
	test01(); //一维
	test02(); //位置和大小
	test03();//最大值
	test04();//倒置
	test05();//冒泡排序
}



二维数组

#pragma warning(disable:4996)
#include<stdio.h>
#include<stdlib.h>


//数组
void test01() {
 /*
1. 数据类型 数组名[ 行数 ][ 列数 ];
2. 数据类型 数组名[ 行数 ][ 列数 ] = { {数据1,数据2 } ,{数据3,数据4 } };
3. 数据类型 数组名[ 行数 ][ 列数 ] = { 数据1,数据2,数据3,数据4};
4. 数据类型 数组名[ ][ 列数 ] = { 数据1,数据2,数据3,数据4};
 */
 //方式4
//数据类型 数组名[][列数] = { 数据1,数据2 ,数据3,数据4 };
	int arr4[][3] = { 1, 2, 3, 4, 5, 6 ,7 }; //行数可以省略
	for (int i = 0; i < 3; i++)
	{
		//内层循环
		for (int j = 0; j < 3; j++)
		{
			printf("%d ", arr4[i][j]);
		}
		printf("\n");
	}
}
 
void test02() {
	int arr[2][3] = {
   { 1, 2, 3 },
   { 4, 5, 6 },
	};
	//可以查看整个数组占用内存空间大小
	printf("二维数组占用空间为%d\n", sizeof(arr)); //24
	printf("二维数组每行占用空间为%d\n", sizeof(arr[0])); //12
	printf("二维数组每个元素占用空间为%d\n", sizeof(arr[0][0])); // 4
	//二维数组 行数 列数
	printf("二维数组行数:%d\n", sizeof(arr) / sizeof(arr[0]));
	printf("二维数组列数:%d\n", sizeof(arr[0]) / sizeof(arr[0][0]));
	//可以查看二维数组首地址
	printf("二维数组首地址 %d\n", arr);
	printf("二维数组第一行地址 %d\n", arr[0]);
	printf("二维数组第二行地址 %d\n", arr[1]);
	printf("第一个元素的地址:%d\n", &arr[0][0]);
	printf("第二个元素的地址:%d\n", &arr[0][1]);

}
// 成绩表 3科 3名同学
void test03() {
	int arr[][3] = {
		{66,77,88},
		{0,0,100},
		{100,99,99}
	};
	// 行数和列数
	int row = sizeof(arr) / sizeof(arr[0]);
	int col = sizeof(arr[0]) / sizeof(arr[0][0]);

	// 外层行,内层列
	for (int i = 0; i < row ; i++) {
		int sum = 0;
		for (int j = 0; j < col; j++) {
			sum += arr[i][j];
		}
		printf("第%d个同学总分为%d\n", i + 1, sum);
	}

 
}

// 字符数组
void test04() {
	//逐个初始化字符数组
   //char arr[5] = { 'h','e','l','l','o' }; //error,因为没有\0位置,输出乱码
   //char arr[6] = { 'h','e','l','l','o' }; // \0本质就是0
   //遍历字符数组
   //for (int i = 0; i < sizeof(arr) / sizeof(char); i++)
   //{
   // printf("%c", arr[i]);
   //}
   //printf("\n");
   //利用双引号初始化字符数组
	char arr[6] = "hello"; //自动在字符串后面加 \0
	printf("%s\n", arr);
	printf("sizeof = %d\n", sizeof(char));
	printf("sizeof = %d\n", sizeof(arr));
	printf("%d\n", strlen(arr));//strlen(字符数组名) 统计字符串长度 不统计\0
	char arr3[] = "hello\0world";
	printf("arr3 strlen = %d\n", strlen(arr3));//5 统计到\0结束
	printf("arr3 sizeof = %d\n", sizeof(arr3));//12

}
void test05() {
	//创建字符数组 并且初始化为空
	char arr1[16] = "";
	//char arr1[16] = { 0 };
	scanf("%s", arr1); //遇到空格 结束输入
	printf("%s\n", arr1);
	//arr1 = "hello world"; error 不可以直接等号赋值
	strcpy(arr1, "hello world"); // 头文件 string.h
	printf("%s\n", arr1);

	char arr[16] = { 0 };
	gets(arr); //遇到换行符才结束,可以输入空格
	//不会检测数据是否溢出,一旦溢出,程序终止
	printf("%s\n", arr);

	char arr2[16] = { 0 };
	fgets(arr2, sizeof(arr2), stdin); //stdin 标准输入设备,默认代表键盘
	printf("%s\n", arr2);

	char arr3[16] = "hello world";
	printf("%s\n", arr3); //常用
	puts(arr3); //自带换行
	fputs(arr3, stdout); //stdout 代表标准输出设备 默认屏幕 不带换行

}





void main() {
	// 二维本质是一维,地址连续的
	test01(); // 数组表示
	test02(); // 数组大小和首地址就是数组名
	test03(); // 计算总分
	test04(); // 字符数组,strlen
	test05(); // 字符数组输入 fgets
}


结构体

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>


// 结构体定义
//结构体属于用户自定义的数据类型,允许用户存储不同的数据类型
struct student
{
	int id; //学号
	char name[64]; //姓名
	float score; //分数
	int age; //年龄
};


void test01()
{
	//通过结构体类型,创建结构体变量
	//给结构体变量赋值的时候要按照顺序赋值
	struct student s1 = { 1, "Tom", 99.9, 18 };
	//通过 '.' 符号 可以找到具体的成员
	printf("id = %d\n", s1.id);
	printf("name = %s\n", s1.name);
	printf("score = %.1f\n", s1.score);
	printf("age = %d\n", s1.age);
}
//在定义结构体时候,顺便创建结构体变量
struct student2
{
	int id; //学号
	char name[64]; //姓名
	float score; //分数
	int age; //年龄
}s; //s代表 通过struct sutdent2创建的结构体变量
void test02()
{
	s.id = 2;
	//s.name = "Jerry"; //error
	strcpy(s.name, "Jerry");
	s.score = 80;
	s.age = 19;
	printf("id = %d\n", s.id);
	printf("name = %s\n", s.name);
	printf("score = %.1f\n", s.score);
	printf("age = %d\n", s.age);
}

struct hero
{
	int id; //id号
	char name[64]; //姓名
	int height; //身高
	int age; //年龄
};

//结构体数组
void test03()
{
	struct hero arr[5] =
	{
	{ 1, "刘备", 160, 30 },
	{ 2, "张飞", 180, 31 },
	{ 3, "关羽", 170, 32 },
	{ 4, "赵云", 188, 34 },
	{ 5, "吕布", 196, 33 } //最后一行的 ',' 可以省略
	};
	int num = sizeof(arr) / sizeof(struct hero);
	struct hero* p = arr;
	for (int i = 0; i < num; i++)
	{
		printf("id = %d name = %s height = %d age = %d\n", arr[i].id,arr[i].name, arr[i].height, arr[i].age);
		printf("id = %d name = %s height = %d age = %d\n", (arr+i)->id, (arr + i)->name, (arr + i)->height, (arr + i)->age);
		printf("id = %d name = %s height = %d age = %d\n", (p+i)->id, (p + i)->name, (p + i)->height, (p + i)->age);
	}
	//求年龄的平均值
	int sum = 0;
	for (int i = 0; i < num; i++)
	{
		sum += arr[i].age;
	}
	printf("年龄平均值为:%d\n", sum / num);
}

struct stu {
	char name[64];// 姓名
	int age; //年龄
	int score; // 成绩
};

struct teacher{
	int id;
	char name[64];
	struct stu s1;
};

void test04() {
	struct teacher t1;
	t1.id = 1000;
	strcpy(t1.name, "t1");
	strcpy(t1.s1.name, "s1");
	t1.s1.age = 18;
	t1.s1.score = 80;
	printf("%d\n", t1.id);
	printf("%s\n", t1.s1.name);
	
}

//学生结构体定义
struct students
{
	//成员列表
	char name[64]; //姓名
	int age; //年龄
	int score; //分数
};
//值传递
void printStudent( const struct students stu)
{
	//stu.age = 28;
	printf("子函数中 姓名:%s 年龄:%d 分数: %d\n", stu.name, stu.age,
		stu.score);
}
//地址传递
void printStudent2(const struct students*   stu)
{
	//stu->age = 28;
	printf("子函数中 姓名:%s 年龄:%d 分数: %d\n", stu->name, stu->age, stu -> score);
}
 


 

int main() {

	test01();//结构体定义
	test02();//结构体定义
	//总结1:定义结构体时的关键字是struct,不可省略
	//总结2:创建结构体变量时,关键字struct可以省略
	//总结3:结构体变量利用操作符 ''.'' 访问成员
	test03();//计算平均值
	test04();//嵌套
	struct students stu = { "张三",18,100 };
	//值传递 加const
	printStudent(stu);
	printf("主函数中 姓名:%s 年龄:%d 分数: %d\n", (&stu)->name, (&stu)->age, (&stu)-> score);
	//地址传递 加const
	printStudent2(&stu);
	printf("主函数中 姓名:%s 年龄:%d 分数: %d\n", stu.name, stu.age, stu.score);

	system("pause");
	return 0;

}

指针

#pragma warning(disable:4996)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>



//指针的使用
void test01()
{
	int a = 10;
	//定义一个指针
	int* p;
	//建立关系
	p = &a;
	printf("&a = %d\n", &a);
	printf("p = %d\n", p);
	//指针的操作
	*p = 100;
	printf("a = %d\n", a);
    // *p 表示指针p指向地址的值,这个值可能也是地址
	printf("*p = %d\n", *p);
}

test02() {
	//32位下是4个字节,64位下是8个字节
	printf("sizeof int * = %d\n", sizeof(int*));
	printf("sizeof char * = %d\n", sizeof(char*));
	printf("sizeof float * = %d\n", sizeof(float*));
	printf("sizeof double * = %d\n", sizeof(double*));
}

//空指针
void test03()
{
	int* p = NULL; //NULL本质就是 0
	//访问空指针的存储内容 会报错
	//内存地址编号为 0 ~ 255之间的系统占用的内存,用户不可以访问
	//printf("%d\n", *p); //error 空指针不可以访问
}
//野指针
void test04()
{
	//利用指针变量p指向非法内存空间 0x1100
	//int* p = 0x1100;
	//printf("%d\n", *p);
}
//注意事项:不要操作未初始化的指针变量
void test05()
{
	//int* p; //也属于野指针
	//*p = 100;
	//printf("%d\n", *p);

}

void test06() {
	int a = 10;
	const int* p = &a; //*p只读 p可读可写 等价于 int const *p = &a;
	//*p = 100; //error 指针指向的值 不可以修改
	int b = 20;
	p = &b; //success 指针的指向可以修改


}
void test07() {
	int a = 10;
	int* const p = &a;//*p可读可写 p只读
	*p = 20; //success 指针指向的值 可以修改的
	int b = 20;
	//p = &b; // error 指针的指向不可以修改
}
void test08() {
	int a = 10;
	const int* const p = &a; //等价于 int const * const p = &a;
	//*p = 100; error 指针指向的值不可以改
	int b = 20;
	//p = &b; error指针的指向不可以改

}

//利用指针操作数组
void test09()
{
	int arr[5] = { 1, 2, 3, 4, 5 };
	//定义一个指针变量,接受数组名
	int* p = arr;
	for (int i = 0; i < 5; i++)
	{	
		// i 是1 表示一个int的大小及4个字节
		printf("%d ", *(p + i));
		printf("%d ", p[i]);
	}
	printf("\n");
	//p 和arr区别,不越界情况下
	printf("sizeof arr = %d\n", sizeof(arr)); //20
	printf("sizeof p = %d\n", sizeof(p)); //4
	int* p2 = &arr[2];
	// *(p2+1)
	printf("%d\n", p2[1]); // 4
	// *(p2-1)
	printf("%d\n", p2[-1]);// 2
}
//值传递
//通过一个函数实现两个整型数字交换的函数
void mySwap(int a, int b)
{
	int temp = a;
	a = b;
	b = temp;
	printf("mySwap中的a = %d\n", a); // 20
	printf("mySwap中的b = %d\n", b); // 10
}
void test10()
{
	int a = 10;
	int b = 20;
	//值传递的 形参是改变不了实参的
	mySwap(a, b);
	printf("test10中的a = %d\n", a);
	printf("test10中的b = %d\n", b);
}

//  地址传递
void mySwap2(int* p1, int* p2)
{
	int temp = *p1;
	*p1 = *p2;
	*p2 = temp;
	printf("mySwap2中的*p1 = %d\n", *p1);
	printf("mySwap2中的*p2 = %d\n", *p2);
}
void test11()
{
	int a = 10;
	int b = 20;
	//地址传递的形参 可以修改实参
	mySwap2(&a, &b);
	printf("test11中的a = %d\n", a);
	printf("test11中的b = %d\n", b);
}
void main() {
	test01();//指针
	test02();//指针大小
	test03();//空指针
	test04();//野指针
	test05();//野指针
	//看const右侧紧跟着的是指针还是常量, 是指针就是常量指针,是常量就是指针常量
	test06();//const修饰常量,常量指针 ,指针指向的值,不可修改,指针的指向可以修改
	test07();//const修饰指针,指针常量,指针的指向不可以修改,指向的值可以修改
	test08();//const修饰指针和常量, 都不可以被修改
	test09();//指针数组
	test10();//值传递,形参改不了实参,实参传多少,形参的值就是多少,改不了
	test11();//指针函数,可以改,实参的值
	//如果不想修改实参,就用值传递,如果想修改实参,就用地址传递
	//利用指针找到实参的地址,修改其值

}


函数

#pragma warning(disable:4996)
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include "test.h" //如果用自定义的函数,需要将头文件包含到当前文件中
void test01()
{
	int a = 10;
	int b = 10;
	printf("a + b = %d\n", add(a, b));
	printf("a - b = %d\n", sub(a, b));
}


/*

返回值类型 函数名 (参数列表)
{
函数体语句
return表达式
}

*/


int test() {
	printf("xxxx\n");
	return;
}

int add1(int a, int b) {


 	return a+b;
}

int swap(int a, int b) {
	int t = a;
	a = b;
	b = t;
	printf("a = %d\n", a);
	printf("b = %d\n", b);
}


/*
函数分文件编写一般有4个步骤
1. 创建后缀名为.h的头文件
2. 创建后缀名为.c的源文件
3. 在头文件中写函数的声明
4. 在源文件中写函数的定义
*/


void main() {

	//函数调用
	int res = test();
	int sum = add1(10,20);
	printf("%d", sum);


	// 目前形参修改不了实参
	int x = 10;
	int y = 20;
	swap(x, y);
	printf("b = %d\n", x);
	printf("b = %d\n", y);



	//函数的分文件编写
	test01();


	 
 }

文件

#pragma warning(disable:4996)

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

void test01() {
	FILE* p = NULL;
	p = fopen("b.txt", "w+");
	if (p ==NULL){
		printf("打开失败\n");
			return;
	}

	// 操作文件 写
	char buf[] = "hello world\n";
	int i = 0;
	while (buf[i] != 0)
	{
		fputc(buf[i], p);
		i++;
	}
	 
	//操作文件 读
	char ch = 0;
	while ((ch = fgetc(p)) != EOF)
	{
		printf("ch = %c\n", ch);
	}
	fclose(p);
}

void main() {

	test01();// 打开文件

}

小结

本文只是简单的整理了c语言的基础,里面很重要的有指针,文件操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值