我的CC

C语言学习笔记

为今年考研打基础,重新系统的学习C语言
由于之前学习过JAVA,因此本博客只记录自己在学习中所需记录的知识点。

1、数据类型

数据类型字节数(64位)
short2
int4
long8
char1
float4
double8

注:原生C语言中不含有,利用“零”和“非零”表示。C99中含有Boolean类型变量,但要引入 stdbool.h 文件

2、内存释放
相关应用程序再将自身占用的内存空间释放时,是将该内存空间的操作权限返还给操作系统,内存空间数据不做改变。因此在程序中变量必须要进行初始化,否则再分配内存空间给该变量时,可能会将前程序的垃圾数据赋值给该变量。

3、什么是ASCII码以及字符存储的本质
字符存储的本质也是二进制,而ASCII码就是二进制与字符之间的映射

    char j = 'A';
    printf("%d \n",j);  //输出为65

4、printf函数
printf(“字符串”)
printf(“输出控制符 输出控制符…”,输出参数1,输出参数2…)
输出控制符包括:%d、%ld、%c、%f、%lf、%#X(带0x的十六进制数)

5、scanf函数
scanf(“输入控制符”,输入参数)
  功能:将从键盘输入的字符转化为输出控制符所规定格式的数据,然后 存入输出参数地址的变量中。
  注:当一次给多个变量赋值时,每个变量以回车结束。当输出控制符与非输出控制符混杂时,非输出控制符必须鸳鸯输入。

    int i;
    scanf("%d", &i);
    printf("%#X", i);  //输出为0x64

	int j;
	scanf("m%d",&j);  //此时键盘输入第一个字符必须是m。
					  //输入m123n时,输出为123

6、数组
  (1)C语言中定义一个数组,其在内存中的存储是连续的,并且一个数组所存储数据的数据类型相同。
  (2)数组初始化时,若未将所有数据给予初值,则未给予初值的数据为0。当只进行数组变量声明而未进行初始化时,该数组中数据为垃圾数据。

    int a[5] = {1, 2, 3};

    for (int i=0; i<5; i++){

        printf("a[%d] = %d\n", i, a[i]);
    }
    /*输出结果
    	a[0] = 1
		a[1] = 2
		a[2] = 3
		a[3] = 0
		a[4] = 0
    */
    int a[5];

    for (int i=0; i<5; i++){

        printf("a[%d] = %d\n", i, a[i]);
    }
    /*
	a[0] = 8
	a[1] = 0
	a[2] = 18
	a[3] = 0
	a[4] = 11484480
	*/
	
// 基于以上结论,可以利用如下代码实现数组清零初始化
int a[5] = {0};

  (3)数组名的含义:数组名是一个指针,他指向当前数组首元素

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

int main(void)
{

    int a[5] = {1, 2, 3, 4, 5};
    printf("%#X\t%#X\n", a, &a[0]);

    system("pause");
    return 0;
}
// 输出:0X61FE00        0X61FE00

  (4)数组下标的含义:确定一个数组元素需要两个元素:数组首元素地址及改元素相对于首元素地址的偏移量

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

int main(void)
{

    int a[5] = {1, 2, 3, 4, 5};
    printf("%d\t%d\n", *(a+1), a[1]);

    system("pause");
    return 0;
}

// 输出: 2    2

7、函数
  C语言中自定义函数需要放在调用位置前或将其在开头进行声明。# include <***.h> 就是对对应头文件中定义函数的声明。

# include <stdio.h>  // 利用头文件进行相关函数的声明
void function(void); // 对自定义函数的声明,若无声明,则编译器无法通过编译

int main(void)
{
	function();
	return 0;
}

void function(void)
{
	printf("A");
}

8、指针
  (1)初识指针

int * p; 
int i;
/* 
   p是变量的名字,int * 表示 p 变量存放的是 int 数据类型的变量地址;
   int * p 应该这样理解:定义了一个 int * 类型的变量,变量名为 p;
   *p = i   p = &i;
*/

  (2)野指针

int * p; 
int i = 5;
*p = i;

  int * p; 在内存中开辟了一块内存空间给当前程序,该内存空间在当前程序未进行初始化时,会存有垃圾数据,而声明为指针类型变量后,该程序会将当前垃圾数据作为一个地址(即现在 p 指向一个不明内存地址);而 *p = i;就会把这个不明内存中数据进行修改,不是我们所希望的将 p 指向 i。正确的做法是 p = &i;
  (3)静态内存所存在的问题
1、以静态数组为例,我们在定义一个数组时,必须在定义的时候规定其数组的长度(例如 int a[5]),而当这个数组定义完毕后,他的长度就不能进行改变了,即不能进行动态扩充。
2、我们没有权限去控制内存空间释放的时间,释放内存的权限在于操作系统,只有当该函数运行结束后,为该函数分配的内存空间会被自动释放。
3、我们无法调用某运行结束的函数中所声明的变量,因为该变量已经随函数运行结束而被释放。
4、如何动态定义一个数组

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

int main(void)
{

    int length;
    printf("请输入您所需数组长度:\n");
    scanf("%d", &length);

    int * pArr = (int *) malloc(sizeof(int) * length); // 利用 malloc 函数声明了指定长度的存储 int 类型变量的内存空间

    printf("请为元素赋值:\n");

    for(int i = 0; i < length; i++)
    {
        scanf("%d", &pArr[i]);
    }

    printf("数组所包含元素:\n");

    for(int i = 0; i < length; i++)
    {
        printf("%d\n", pArr[i]);
    }

    system("pause");
}

9、结构体
  (1)为什么要有结构体?
参考 JAVA 中的类,目的是便于模拟现实世界,将具体事务抽象出相关属性封装至一个新的数据结构中,便于操作。
  (2)如何定义结构体

// 方法一(最最常用的方法)
struct Student
{
	int age;
	char sex;
};

// 方法二
// 不推荐使用,该定义方法直接将变量进行声明,当想再次定义新变量时可能会出现错误
struct Student
{
	int age;
	char sex;
}stu;

// 方法三
// 不实用,没有对应数据变量类型名,后续无法进行定义
struct
{
	int age;
	char sex;
}std;

  (3)如何进行结构体初始化

// 以第一种定义方法为例
# include <stdio.h>
# include <stdlib.h>

struct Student
{
	int age;
	char sex;
};  // 注意:此处有分号。将以上语句理解为定义一个新的数据类型即可

int main(void)
{
	struct Student std1 = {20, 'F'}; // 定义时直接初始化
    printf("std1.age = %d, std1.sex = %c\n", std1.age, std1.sex);
	
	struct Student std2;  // 先定义,然后逐个赋值
	std2.age = 21;
	std2.sex = 'M';
    printf("std2.age = %d, std2.sex = %c\n", std2.age, std2.sex);
	
    struct Student std3; // 利用指针进行操作
	struct Student * p;; 
    p = &std3;
	p -> age = 22;  // 在计算机内部会被处理为 (*p).age = 22;
	p -> sex = 'M';
    printf("std3.age = %d, std3.sex = %c\n", p -> age, p -> sex);
	
    system("pause");

	return 0;
}

10、枚举
  将一件事物所有可能的取值进行封装,增强程序的安全性。其内部按照整型变量进行存储,第一个元素为0、第二个为1,以此类推。

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

enum WeekDay
{
    Mon, Tues, Wed, Thur, Fri, Sat, Sun
};

int main(void)
{

    enum WeekDay day = Mon;
    printf("%d", day);  // 输出:0

    system("pause");
}

杂记

1、Linux 下 make 的使用
  首先建立 makefile(其他文件名也可,使用 make -f filename 即可,不添加 -f 默认搜索 makefile 文件进行执行)文件,在其中编写相关依赖及所需执行的 gcc 代码,然后运行 make 即可。
在这里插入图片描述
2、typedef 用法
作用:为数据类型的名字起一个别名,多用于结构体中,可简化变量声明时的工作量。

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

typedef int ZHENGXING; // 为 int 数据类型起了个别名 ZHENGXING

typedef struct Student
{
    int stdNo;
    char sex;
}* pSTD, STD; // 为 struct Student * 起别名为:pSTD
              // 为 struct Student 起别名为:STD

int main(void)
{
    ZHENGXING i = 1;
    printf("i = %d\n", i);

    STD std;  // 等价于 struct Student std;
    pSTD pStd = &std; // 等价于 struct Student * pStd = &std;

    pStd->sex = 'F';
    printf("%c\n", pStd->sex);

    system("pause");
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值