C语言所有知识简单复习

目录

一、如何写代码

0x00 首先写主函数

0x01 然后写代码

0x02 最后运行程序

二、数据类型

0x00 基本类型

0x01 格式说明

0x03 数据类型的大小

 三、变量与常量

0x00 创建变量

0x01 全局变量和局部变量

0x02 scanf 函数

0x03 变量的使用

0x04 作用域和生命周期

0x05 常量

四、字符串&转义字符&注释

0x00 字符串

0x01 计算字符串长度

0x02 ASCII 码值

0x03 转义字符

0x04 注释

五、分支和循环

 0x00 if 语句

六、函数

七、数组

八、操作符简单介绍

0x00 算数操作符

0x01 移位操作符

0x02 位操作符

0x03 赋值操作符

0x04 单目操作符

0x05 逻辑操作符

0x06 条件操作符

0x07 逗号表达式

0x08 下标引用操作符

0x09 函数引用操作符

九、关键字

0x00 常见关键字

0x01 define

十、指针初探

0x00 指针介绍

0x01 解引用操作

0x02 指针的大小

十一、结构体

0x00 什么是结构体


一、如何写代码

0x00 首先写主函数

❓ 何为main函数?

main函数,又称主函数,是程序执行的起点。

1. 主函数是程序的入口

2. 主函数有且只有一个

📚 一个工程中可以有多个“.c文件”,但是多个“.c文件”中只能有一个“main 函数”

0x01 然后写代码

💬  "你好,世界!"

#include <stdio.h> //头文件

int main()

{

printf("hello world!\n");

return 0;

}

0x02 最后运行程序

🔨 编译 + 链接 + 运行代码

快捷键: Ctrl + F5( VS2013 )

[调试] -> [选择' 开始执行(不调试)']

❓ “是不是有什么一闪而过了?”

因为程序执行得太快,所以没有看到结果。

为了看到结果,我们需要设置一下 VS2013 的属性 ( VS2019不需要设置项目属性 )

[解决方案资源管理器] -> [右键项目名称] -> [属性] -> [链接器] -> [系统]

-> [子系统] -> [选择' 控制台(/SUBSYSRTEM:CONSOLE) ']

🚩 运行结果如下:

二、数据类型

0x00 基本类型

📚 这里先做些简单的介绍:

💬 基本数据类型的使用方法:

int main()

{

char ch = 'a';

int age = 20;

float weight = 50.8;

double d = 0.0;


return 0;

}

0x01 格式说明

📚 格式说明由“%”和格式字符组成:

💬 演示:

int main()
{
printf("%d\n", 100);
printf("%c\n", 'a');

float foo = 5.0;
printf("%f\n", foo);

double pi = 3.14;
printf("%.2lf\n", pi); // .xf(x为小数点保留几位数)

char str1[] = "hello";
printf("%s\n", str1);

int a = 10;
printf("%p\n", &a);

return 0;
}

🚩 运行结果: 100 a 5.000000 3.14 hello 0000000000061FE04

0x03 数据类型的大小

📺 32位系统下:

📚 关键字 sizeof :获取数据在内存中所占用的存储空间,以字节为单位计数

💬 使用方法演示:

int main()
{
char a = 'A';
printf("%d\n", sizeof(a))
printf("%d\n", sizeof a) //求变量时可省略括号 ✅

printf("%d\n", sizeof(char));
printf("%d\n", sizeof char); //error!但是求字符类型时不可省略 ❌

return 0;
}

🚩 运行结果:1

💬 使用 sizeof 求元素个数:

int main()
{
int arr[] = {1,2,3,4,5,6,7,8,9,10};
printf("%d\n", sizeof(arr)); //计算的是数组的总大小,单位是字节
printf("%d\n", sizeof(arr[0])); //计算的是数组首字符大小
int sz = sizeof(arr) / sizeof(arr[0]);
printf("%d\n", sz);

return 0;
}

🚩 运行结果: 40  4  10

📚 计算机中的单位: bit - 比特位

计算机中识别二进制:1&0         8进制:0-7        10进制:0-9

 三、变量与常量

0x00 创建变量

 💬 代码演示:

#include <stdio.h>

int main()
{
int age = 20;
double weight = 62.5;

age = age + 1;
weight = weight - 10;
printf("%d\n", age);
printf("%lf\n", weight);

return 0;
}

0x01 全局变量和局部变量

💬 局部变量和全局变量的名字相同时,局部变量优先,对局部影响:

int var = 100;
int main()
{
int var = 10;
printf("%d\n", var);

return 0;
}

🚩 运行结果: 10

0x02 scanf 函数

💬 使用方法演示:

int main()
{
int a = 0;
scanf("%d", &a);
printf("%d", a);

return 0;
}

0x03 变量的使用

💬 使用方法演示:写一个代码求两个变量的和

int main()
{
int a = 0;
int b = 0;
int sum = 0;

scanf("%d %d", &a, &b);
sum = a + b;
printf("sum = %d\n", sum);

return 0;
}

❗ 如果编译器发出了警告,说 scanf 不安全,在代码前面添加

#define _CRT_SECURE_NO_WANRINGS 1

即可,当然还有其他方法可以解决,这里就不细说了。

🚩 运行结果如下:(假设输入了 1 2)

sum = 3

0x04 作用域和生命周期

📚 作用域(scope)

程序设计概念,通常来说,一段程序代码中所用到的名字并不总是有效/可用 的 而限定这个名字的可用性的代码范围就是这个名字的作用域。

全局变量的作用域是整个工程。

局部变量的作用域是变量所在的局部范围。

📚 生命周期:

变量的生命周期:变量的创建和销毁之间的时间段

局部变量的生命周期:进入作用域生命周期开始,出作用域生命周期结束。

全局变量的生命周期:整个程序的生命周期。

💬 局部变量的生命周期:

int main()
{
{
int a = 10;
printf("%d\n", a);
}
printf("%d\n", a); //error 生命周期结束了
}

💬 全局变量的生命周期

//声明一下变量
extern int g_val;
int main()
{
printf("%d", g_val);
}

0x05 常量

📚 定义:C语言中常量和变量的定义的形式有所差异

C语言的常量分为以下几种:

① 字面常量:直接写

② const 修饰的常变量:用 const 定义

③ #define 定义的标识符常量:宏定义

④ 枚举常量:可以一一列举的常量

💬 字面常量:

int main()
{
3.14;
10;
'a';
"abcdef";
}

💬 const 修饰的常量:

int main()
{
const int num = 10;
num = 20; //error, 不能修改
printf("num = %d\n", num);
}

🚩 运行结果: 10

💬 #define 定义的标识符常量:

#define MAX 10000 // 不写=,不加分号!

int main()
{
int n = MAX;
ntf("%d\n", n);
}

🚩 运行结果:10000

💬 枚举常量:

//性别
enum Sex {
//这种枚举类型的变量的未来可能取值
//枚举常量
MALE = 3, //赋初值
FEMALE,
SECRET
};
int main()
{
enum Sex s = MALE;
printf("%d\n", MALE);
// MALE = 3 error 不可修改
printf("%d\n", FEMALE);
printf("%d\n", SECRET);

return 0;
}

📌 注意事项:

const 只是一个有常属性的变量,本质上仍然为变量!arr[], 数组的大小必须是常量!

int main()
{
const int n = 10; //n是变量,但是又有常属性,所以我们说n是常变量
int arr[n] = {0}; // 仍然不可以,因为n是变量,只是有常属性而已

return 0;
}

💬 #define 定义的可以,宏定义用得最多的地方是在数组中用于指定数组的长度:

#define N 10
int main()
{
int arr[N] = {0};

return 0;
}

📌 注意事项:

枚举常量虽然是不能改变的,但是通过枚举常量创造出来的变量是可以改变的!

enum Color
{
// 枚举常量
RED,
YEELOW,
BULE
};

int main()
{
enum Color c = BULE; //我们创建一个变量c,并将BULE赋给它
c = YEELOW; //这时将YEELOW赋给它,完全没有问题 ✅
BULE = 6; //error!枚举常量是不能改变的 ❌
return 0;
}

四、字符串&转义字符&注释

0x00 字符串

📚 定义:

"hello world."

这种由双引号(Double Quote)引起来的一串字符称为字符串字面值(String Literal)

📚 关于斜杠零:

字符串的结束标志是一个 \0 转义字符。

在计算字符串长度的时候 \0 是结束标志,不算字符串的内容!

💬 下面代码,打印的结果是什么?为什么?

int main()
{
char arr1[] = "abc"; //数组
// "abc" -- 'a' 'b' 'c' '\0'
// 这里面,'\0' 字符串的结束标志
char arr2[] = {'a', 'b', 'c'};
char arr3[] = {'a', 'b', 'c', '\0'};

printf("%s\n", arr1);
printf("%s\n", arr2);
printf("%s\n", arr3);

return 0;
}

🚩 打印结果如下:

0x01 计算字符串长度

📚 strlen 函数:返回字符串的长度

📜 使用时需引入头文件 <string.h>

💬 代码演示:

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

int main()
{
char arr1[] = "abc";
char arr2[] = {'a', 'b', 'c'};
printf("%d\n", strlen(arr1));
printf("%d\n", strlen(arr2));

return 0;
}

 🚩 运行结果如下:  3   随机值

 

0x02 ASCII 码值

📚 ASCII (American Standard Code for Information Interchange)

“是基于拉丁字母的一套电脑编码系统,主要用于显示现代英语和其他西欧语言。它是最通用的信息交换标准,并等同于国际标准ISO/IEC 646。ASCII第一次以规范标准的类型发表是在1967年,最后一次更新则是在1986年,到目前为止共定义了128个字符”

0x03 转义字符

📚 转意字符顾名思义就是转变字符的意思。

💬 让斜杠就是斜杠:

int main()
{
printf("c:\\test\\32\\test.c"); //再加一个斜杠,规避转义字符检测

return 0;
}

 🚩 运行结果:  c:\test\32\test.c

💬 三字母词、输出单引号、ddd、xdd:

int main()
{
printf("(are you ok?\?)\n"); // ??) -- ] - 三字母词
printf("%c\n", '\''); //输出一个单引号
printf("%s\n", "\""); //输出一个双引号

printf("%c\n", '\130');//8进制的130是10进制的多少呢?
//X - ASCII码值是88
printf("%c\n", '\101'); // A- 65 - 8进制是:101
printf("%c\n", '\x30'); //48 - '0'

return 0;
}

🚩 运行结果:  (are you ok??) ' " X A 0

❓ 下列代码打印的结果是什么?

int main()
{
printf("%d\n", strlen("c:\test\328\test.c"));

return 0;
}

💡 答案:14

0x04 注释

📚 代码中有不需要的代码可以直接删除,也可以注释掉

代码中有些代码比较难懂,可以加一下注释文字

有两种风格:

① C语言风格的注释   /* xxxxxx */

缺陷:不能嵌套注释

② C++风格的注释    //xxxxxxxxx

优点:可以注释一行也可以注释多行

快捷键:Ctrl + /?

💬 演示:

/* C语言风格注释
int Add(int x, int y) {
int z = 0;
z = x + y;
return z;
}
*/

int Add(int x, int y) {
return x + y;
}

int main()
{
// C++注释风格
// int a = 10;
printf("%d\n", Add(1,2)); //调用Add函数

return 0;
}

五、分支和循环

 0x00 if 语句

📚 定义:if 语句是指编程语言(包括c语言、C#、VB、java、汇编语言等)中用来判定所给定的条件是否满足,根据判定的结果(真或假)决定执行给出的两种操作之一。

💬 选择语句代码演示:

int main()
{
int a = 10;
int b = 20;

if(a>b) {
printf("a比b大\n") ;
} else {
printf("b比a大\n");
}

return 0;
}

🚩 运行结果:  b比a大

❓  C语言中如何实现循环呢?

1. while 语句

2. for 语句

3. do ... while 语句

这里我们着重先了解下 while 语句。

📚 while 循环的基本概念:while是计算机的一种基本循环模式。当满足条件时进入循环,进入循环后,当条件不满足时,跳出循环。

💬 演示代码:敲三万行代码

#include <stdio.h>

int main()
{
int line = 0;
while(line < 30000) {
printf("敲代码: %d\n", line);
line++;
}
if(line == 30000) {
printf("恭喜你敲满30000行代码!\n");
}

return 0;
}

六、函数

❓ 什么是函数?

数学中的函数 f(x) = 2×x+5,C语言中的函数也是一样的。

📚 函数的特点就是:简化代码,代码复用。

💬 代码演示:

int Add (int x, int y) {
    int z = 0;
    z = x + y;
    return z;
}
 
int main()
{
    int num1 = 0;
    int num2 = 0;
    scanf("%d%d", &num1, &num2);
 
    // int sum = num1 + num2;
    // 函数的方式解决
    int sum = Add(num1, num2);
    printf("%d\n", sum);
 
    return 0;
}

七、数组

📚 要存储1-10的数字,怎么存储?

“C语言给了数组的定义:一组相同类型元素的集合”

定义一个整型数组,最多放十个元素:

💬 代码演示:

int main()
{
    int a = 0;
    int b = 0;
    int c = 0;
    int d = 0;
    //...
 
    // 10个整型1-10存起来
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    char ch[5] = {'a', 'b', 'c'}; // 不完全初始化,剩余的默认为0
    
    // 用下标就可以访问元素
    printf("%d\n", arr[0]);
    
    // 打印整个数组
    int i = 0;
    while(i<10) {
        printf("%d ", arr[i]);
        i++;
    }
    
    return 0;
}

八、操作符简单介绍

0x00 算数操作符

❓ 什么是算数操作符?

📚 算术运算符即算术运算符号。是完成基本的算术运算 (arithmetic operators) 符号,就是用来处理四则运算的符号。

💬 代码演示:

int main()
{
    int add = 1 + 1;
    int sub = 2 - 1;
    int mul = 2 * 3;
    float div = 9 / 2.0; //只要有浮点数出现,执行的就是浮点数除法
    int mod = 123 % 10;
 
    return 0;
}

0x01 移位操作符

❓ 什么是移位操作符?

📚 移位运算符在程序设计中,是位操作运算符的一种。移位运算符可以在二进制的基础上对数字进行平移。

💬 代码演示:

int main()
{   
    // 移位操作符 移动的是它的二进制位
    // << 左移
    // >> 右动
    int a = 1;
    // 整形1占4个字节-32bit位
    // 0000000000000000000000000000001
    int b = a<<1;
   // 0000000000000000000000000000010  左边丢弃,右边补0
    printf("%d\n", b);
    printf("%d\n", a);
 
    return 0;
}

🚩  运行结果: 2 1

0x02 位操作符

❓ 什么是位操作符?

📚 位操作是程序设计中对位模式按位或二进制数的一元和二元操作

💬 代码演示:

#include <stdio.h>
 
int main()
{
    //位操作 依然是二进制位
 
    // & 按位与   都为真,则返回真,只要出现假,就返回假
    int a = 3; //真
    int b = 5; //真
    int c = a&b; //按位与
    // 011
    // 101
    // 001
    // R→ 1 //真
    printf("%d\n", c);
    
    int d = a|b;// 按位或  有真则为真,无则假,只要出现真,就返回真
    // 011
    // 101
    // 111
    // R→ 7
    printf("%d\n", d);
 
    int e = a^b;// 按位异或  相同为假,相异为真   11\ 00-> 0   10 -> 1
    //异或的计算规律
    //对应的二进制位相同,则为0
    //对应的二进制位相异,则为1
    // 011
    // 101
    // 110
    // R→
    printf("%d\n", e);
    
    return 0;
}

0x03 赋值操作符

❓ 什么是赋值操作符?

📚 赋值运算符是双目运算符,用在赋值表达式中。赋值运算符将值存储在运算符左边操作数指定的变量中。

💬 代码演示:

#include <stdio.h>
 
int main()
{
    int a = 10;
    a = 20; // “=” 赋值  “==” 判断相等
 
    a = a+10; //1
    a += 10; // 2
    
    a = a-20;
    a -= 20;
 
    a = a & 2;
    a &= 2;
    //这些操作叫做 复合赋值符
    
    return 0;
}

0x04 单目操作符

❓ 什么是单目操作符?

📚 单目操作符,也就是只接受一个操作数的操作符。

💬 逻辑反操作 !

int main()
{
    //0表示假,非0就是真
    int a = 5;
    printf("%d\n", !a);
 
    if(a) {
        //如果a为真,做事
    }
    if(!a) {
        //如果a为假,做事
    }
 
    while(a); //a != 0,做事
    while(!a); //a=0,做事
 
    return 0;
}

💬 按位取反 ~

int main()
{
    int a = 0;
    printf("%d\n", ~a);
    // ~ 按(二进制)位取法 
    //把所有二进制位的数字,1变成0,0变成1
 
    //整数a
    // 0
    // 00000000000000000000000000000000
    // 11111111111111111111111111111111  ~a
    // 数据在内存中存储的是补码
    // 一个整数的二进制表示有三种: 原码 反码 补码
    // 负数的计算  -1:
    // 10000000000000000000000000000001 (原码)
    // 11111111111111111111111111111110 (反码)
    // 11111111111111111111111111111111 (补码) -> 在内存中存的
 
    // 正的整数: 原码、反码、补码相同
 
    return 0;
}

💬 前置++

int main()
{
    int a = 10;
    int b = ++a; //前置++, 先++后使用
    
    printf("%d\n", b); //11
    printf("%d\n", a); //11
 
    return 0;
}

💬 后置++

int main()
{
    int a = 10;
    int b = a++; //后置++,先使用再++
 
    printf("%d\n", b);
    printf("%d\n", a);
 
    return 0;
}

💬 强制类型转换:

int main()
{
    int a = (int)3.14; //强制类型转换
    printf("%d\n", a);
 
    return 0;
}

0x05 逻辑操作符

📚 逻辑运算符或逻辑联结词把语句连接成更复杂的复杂语句

逻辑与:两个都为真即为真(and)

逻辑或:一个为真即为真(or)

💬 逻辑与 &&

int main()
{
    int a = 3;
    int b = 5;
    int c = a && b;
    printf("%d\n", c); //1
 
    return 0;
}

💬 逻辑或 ||

int main()
{
    int a = 3;
    int b = 0;
    int c = a||b;
    printf("%d\n", c); //1
    
    return 0;
}

0x06 条件操作符

📚 条件操作符就是三目操作符

exp1成立,exp2计算,整个表达式的结果是:exp2的结果。

exp1不成立,exp2计算,整个表达式的结果是:exp3的结果。

💬 条件操作符的用法:

int main()
{
    //exp1成立,exp2计算,整个表达式的结果是:exp2的结果
    //exp1不成立,exp3计算,整个表达式的结果是exp3的结果
    int a = 0;
    int b = 3;
    int max = 0;
 
    /* 等价于
    if(a>b) {
        max = a;
    } else {
        max = b;
    }
    */
 
    max = a>b ? a : b;
 
    return 0;
}

0x07 逗号表达式

📚 逗号表达式:逗号隔开的一串表达式。

逗号表达式是从左向右依次计算的。

整个表达式的结果是最后一个表达式的结果。

💬 逗号表达式的用法演示:

int main()
{
    (2, 3+5, 6);
    int a = 0;
    int b = 3;
    int c = 5;
            // a=5   c=5-4  b=1+2
    int d = (a=b+2, c=a-4, b=c+2);
    printf("%d\n", d); // 3
 
    return 0;
}

0x08 下标引用操作符

📚  [] 就是下标引用操作符。

💬 演示:

int main()
{
    int arr[10] = {1,2,3,4,5,6,7,8,9,10};
    printf("%d\n", arr[5]); // 6
 
    return 0;
}

0x09 函数引用操作符

📚 调用函数时,函数名后面的()就是函数调用操作符

💬 演示:

int main()
{   
    printf("hehe\n");
    printf("%d", 100);
 
    return 0;
}

九、关键字

0x00 常见关键字

📚 C语言提供的关键字:

1. C语言提供的,不能自己创建关键字

2. 关键字不能做变量名

 这里我们来简单地介绍几个:

💬 auto - 自动的

int main()
{
    {
        int a = 10; //自动创建,自动销毁的 - 自动变量
        // auto省略掉了
        auto int a = 10;
        // auto新的C语言中也有其它用法 - 暂时不考虑
    }
 
    return 0;
}

💬 register - 寄存关键字

int main()
{
    // 大量/频繁使用的数据,想放在寄存器中,提升效率
    register int num = 100; //建议num的值存放在寄存器中
    //是不是最终放到寄存器中是编译器说的算
 
    // 其实现在编辑器已经很聪明了,
    // 就算你不主动加register,它也会帮你存到寄存器中。
    return 0;
}

💬 typedef - 类型重命名

// 这种罗里吧嗦的变量我们可以把它重命名一下
typedef unsigned int u_int;
int main()
{
    unsigned int num = 100;
    u_int num2 = 100; //和上面是等价的
 
    return 0;
}

📚 static - 静态的

1. static修饰局部变量

2. static修饰全局变量

3. static修饰函数

💬 static修饰局部变量

函数中局部变量:

声明周期延长:该变量不随函数结束而结束

初始化:只在第一次调用该函数时进行初始化

记忆性:后序调用时,该变量使用前一次函数调用完成之后保存的值

存储位置:不会存储在栈上,放在数据段

void test() {
    static int a = 1; //不销毁,生命周期变长了
    a++;
    printf("%d ", a);
}
 
int main()
{
    int i = 0;
    while(i<10) {
        test();
        i++;
    }
 
    return 0;
}

🚩 运行结果: 2 3 4 5 6 7 8 9 10 11

💬 static修饰全局变量

改变该变量的链接属性,让该变量具有文件作用域,即只能在当前文件中使用。

① Global.c:

static int g_val = 2021;
// static 修饰全局变量,
// 使得这个全局变量只能在自己所在的源文件(.c)内部可以使用
// 其他的源文件不能使用!
 
// 全局变量,在其他原文件内部可以被使用,是因为全局变量具有外部链接属性
// 但是被static修饰之后,就变成了内部链接属性,
// 其他的源文件就不能链接到这个静态的全局变量了!

② test.c:

extern int g_val;
 
int main()
{
    printf("%d\n", g_val);
 
    return 0;
}

🚩 运行结果: test.obj : error LNK2001: 无法解析的外部符号 _g_val

💬 static修饰函数

改变该函数的链接属性,让该函数具有文件作用域,即只能在当前文件中使用。

① Add.c:

//static修饰函数,
static int Add(int x, int y) {
    return x + y;
}

💬 test1.c:

extern int Add(int, int); //声明外部函数
 
int main()
{
    int a = 10;
    int b = 20;
    int sum = Add(a, b);
    printf("sum = %d\n", sum);
 
    return 0;
}

🚩 运行结果:

test.obj : error LNK2019: 无法解析的外部符号 _Add,该符号在函数 _main 中被引用

0x01 define

📚 define 是一个预处理指令:

1. define 定义标识符常量

2. define 定义宏

💬 define 定义标识符常量:

#define MAX 1000
int main()
{
    printf("%d\n", MAX);
    return 0;
}

💬 define 定义宏:

#define ADD(X, Y) X+Y
#define ADD1(X, Y) ((X)+(Y))
int main()
{
    printf("%d\n", 4*ADD(2, 3));
    //             4*2+3 = 11
    printf("%d\n", 4*ADD1(2, 3));
    //             4*(2+3) = 20
    
    return 0;
}

十、指针初探

0x00 指针介绍

❓ 什么是指针?

指针就是地址,地址就是指针。

指针,是C语言中的一个重要概念及其特点,也是掌握C语言比较困难的部分。指针也就是内存地址,指针变量是用来存放内存地址的变量,不同类型的指针变量所占用的存储单元长度是相同的,而存放数据的变量因数据的类型不同,所占用的存储空间长度也不同。有了指针以后,不仅可以对数据本身,也可以对存储数据的变量地址进行操作。

💬 变量都有地址,取出变量的地址如下:

int main()
{
    int a = 10; // a在内存中要分配空间 - 4个字节
    &a; // 取出num的地址
    printf("%p\n", &a); //%p - 以地址的形式打印
    
    return 0;
}

🚩 打印出来的是a的地址

💬 定义指针变量,存储地址

* 说明 pa 是指针变量

int 说明 pa 执行的对象是 int 类型的

int main()
{
    int a = 10;
    int* pa = &a; // pa是用来存放地址的,在C语言中叫pa的是指针变量
    
    char ch = 'w';
    char* pc = &ch;
    
    return 0;
}

0x01 解引用操作

如果把定义指针理解为包装成快递,那么“解引用操作”就可以理解为是拆包裹

拆出来的值就是那个变量的值,甚至还可以通过“解引用”来修改它的值。

💬 解引用操作用法:

int main()
{
    int a = 10;
    int* pa = &a;
 
    *pa = 20; // * 解引用操作   *pa就是通过pa里边的地址,找到a
    printf("%d\n", a); //20
    
    return 0;
}

0x02 指针的大小

📚 指针的大小

“指针的大小是相同的”

❓ 为什么相同?

“因为指针是用来存放地址的,指针需要多大空间,取决于地址的存储需要多大空间”

📺 指针是一种复合数据类型,指针变量内容是一个地址,因此一个指针可以表示该系统的整个地址集合,故按照32位编译代码,指针占4个字节,按照64位编译代码,指针占8个字节(注意:不是64位系统一定占8个字节,关键是要按照64位方式编译)。

32位 - 32bit - 4byte

64位 - 64bit - 8byte

💬 sizeof 计算指针的大小:

int main()
{
    printf("%d\n", sizeof(char*));
    printf("%d\n", sizeof(short*));
    printf("%d\n", sizeof(int*));
    printf("%d\n", sizeof(long*));
    printf("%d\n", sizeof(long long*));
    printf("%d\n", sizeof(float*));
    printf("%d\n", sizeof(double*));
 
    return 0;
}

32位下都是 4         64位下都是 8

十一、结构体

0x00 什么是结构体

📚 结构体可以让C语言创建出新的类型

“结构体是C语言中特别重要的知识点,结构体使得C语言有能力描述复杂的类型”

💬 使用结构体描述学生 / 描述书:

// 创建一个学生的类型
struct Stu {
    char name[20]; // 姓名
    int age; // 年龄
    double score; // 分数
};  // ← 不要忘了加分号
 
// 创建一个书的类型
struct Book {
    char name[20];
    float price;
    char id[30];
};

💬 结构体的初始化:

点操作符和箭头操作符

结构体变量.成员

-> 结构体指针->成员

struct Stu {
    char name[20]; // 姓名
    int age; // 年龄
    double score; // 分数
};
 
struct Book {
    char name[20];
    float price;
    char id[30];
};
 
int main()
{
    struct Stu s = {"张三", 20, 85.5}; // 结构体的创建和初始化
    // 点操作符
    printf("1: %s %d %lf\n", s.name, s.age, s.score);
 
    struct Stu* ps = &s;
    printf("2: %s %d %lf\n", (*ps).name, (*ps).age, (*ps).score); // ❎ 可以但不推荐
    // 箭头操作符
    printf("3: %s %d %lf\n", ps->name, ps->age, ps->score); // ✅ 推荐
 
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值