初步了解C语言

C语言的初始学习

一.用C语言写第一个hello world

//c语言代码中一定要有main函数
​
//std-标准
​
//i-input
​
//o-output
​
#include <stdio.h>
​
int main() {
​
    //printf是一个库函数
​
    printf("Hello word");
    return 0;
​
}

(1)main一个是程序的入口,一个程序只能有一个main

(2)创建源文件

.c 源文件

.h 头文件

(3).cpp 编译器会按照c++的语法来编译代码

.c 编译器会按照c的语法来编译代码

二.C语言的数据类型

(1)类型

char         字符数据类型

short        短整型

int            整数型

long         长整型

long long 更长的整形

float         单精度浮点数

double     双精度浮点数

(2)获取字节(1字节=8bit)

#include <stdio.h>
​
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;
​
}

三、变量

1、C语言变量命名规范

  • 只能由字母数字下划线组成,而且数字不能开头

  • 不能使用C语言关键字

  • 区分大小写

【案例说明】

  • 正确变量:name、_age、id_2

  • 错误变量:1name、&123、M.Jack、-name2

  • age和Age是两个不同的变量

2、C语言命名方式推荐

在实际开发过程中,为了提高代码的可读性,通常会使用驼峰命名法:

  • 驼峰命名:第一个单词首字母小写,之后的单词首字母大写,如:myName、myFriendName

3、C语言变量定义并赋值

变量赋值指给变量设置一个具体的值,是用赋值运算符“=”实现,定义及赋值具体语法为:

数据类型 变量名 = 值;

【案例】

int id = 1001;
float score = 12.5;

1.变量指可以变化的量,是用于表述事物属性标识,如:描述学生用到的学号、姓名、性别。

2.在编程中,均使用英文单词进行表示,所以,如上信息可以表示为:id、name、sex。

3.局部变量——在{}内部定义的变量

4.全局变量——在{}外部定义的变量

注:当局部与全局定义变量名相同时,局部优先;但是建议不要将局部和全局名字写的一样

5.变量的使用

(1)用printf()是一个输出函数

(2)用scanf()是一个输入函数

scanf("转义字符", &变量名)
&变量名中,&是取地址操作符,用于传递变量的地址给scanf()函数,使用scanf()时,&后面的变量需要提前定义。
//输入一定不可缺少
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
​
int main() {
    //输入两个整数
    int num1 ;
    int num2 ;
    scanf("%d %d", &num1, &num2);
    //求和
    int sum = num1 + num2;
    //输出结果
    printf("%d", sum);
    return 0;
}

注:有输入必须在源文件的第一行加入

#define _CRT_SECURE_NO_WARNINGS

6.变量的作用域

(1)局部变量的作用域是变量所在的局部范围

(2)全局变量的作用域是整个工程

(申明来自外部的符号 extend)

7.变量的生命周期

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

(2)全局变量:整个程序的生命周期

四、常量

1.c语言中的常量分为以下几种:

(1)字面常量

(2)const修饰的常量变态

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
​
int main() {
    //1.字面常量
    {
        30;
        3.14;
        "w";//字符
        "sdf";//字符串
    }
     //2.constt修饰的常量变态(对象不可以修改)
     {
         const int a = 10; //const修饰的a,本质是变量,但是不可以修改,有常量的属性
         printf("%d\n", a);
     }
    return 0 ;
}

(3)#define定义的标识符常量

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
​
 #define max 100
int main() {
    printf("%d\n",max);
    int a = max;
    printf("%d",a);
    return 0;
}

(4)枚举常量

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
​
enum Color
{
    RED,
    GREEN,
    BLUE
};
int main() {
    int num = 10;
    enum Color c = RED;
    //RED = 20;//err
    return 0;
}

五、字符串+转义字符+注释

1.字符串

字符类型表示1个字符,用char表示,使用时将字符放在''(单引号)中

char name = 'A';

C语言中,没有专门的字符串类型,字符串通常使用字符数组来表示,使用时将字符放在""(双引号)中

注:字符串的标志是一个\0的转义字符。在计算字符长度的时候\0是结束标志,不算作字符串内容。

char name[] = "张三";
strlen();//求字符串长度的一个函数,string length
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
​
int main() {
    char arr[] = "sghduuie";//8
    char arr1[] = { 'a','b','s','f','\0'};//4(如果丢失了“\0”则会直到遇见才会停止)
    int leng = strlen(arr);
    int lon = strlen(arr1);
     printf("%d\n",leng);
     printf("%d", lon);
     return 0;
}

2.转义字符

?在书写连续多个问号时使用,防止他们被解析成三字母词
\`用于表示字符常量`
\"用于表示一个字符产内部的双引号
\\用于表示一个反斜杠,防止它被解释为一个转义序列符
\\a警告字符,蜂鸣
\b退格符
\f进纸符
\n换行
\r回车
\t水平制表符
\v垂直制表符
\ddd ddd表示1~3个八进制的数字。如:\130X
\xdddd表示2个十六进制数字。如:\x30 0

printf()默认只能输出字符串,如果需要输出其他类型的内容,就需要进行格式化输出,可以使用如下转义符表示不同的数据类型:

%d:整数

%c:字符

%f:浮点数

%s:字符串

%f: double类型的数据

六、C语言注释

注释用于向代码添加解释、说明或者提醒,但不会被解释器执行。C语言中有两种主要的注释方式:

  • 单行注释

  • 多行注释

单行注释

// 符号开头,后面的内容直到行尾都会被视为注释。

// 这是一个单行注释,用于解释下面的代码
int x = 10;  // 声明并初始化整型变量x

多行注释

多行注释以 /* 开始,以 */ 结束,可以跨越多行。(不能嵌套注释)

/*
这是一个多行注释示例,
可以跨越多行,
用于注释掉一段代码或者一段说明文字。
*/
int y = 20;  // 声明并初始化整型变量y

七、流程控制结构

C语言中流程控制结构主要包括:顺序结构条件结构循环结构

顺序结构条件结构循环结构

image-20210310171720657

image-20210310171734414

image-20210310171757684

1、条件结构

条件结构也叫选择结构分支结构。可细分为单分支双分支多分支、嵌套结构。

1.1 单分支结构
流程图语法

image-20210311185646931

image-20210311190254562

【实例】

使用代码实现下列描述的逻辑:

输入一个成绩,如果考试成绩达到90分,就去食堂好好吃一顿。

【解答】

#include <stdio.h>
int main(){
float score;
printf("请输入你的成绩:");
scanf("%f",&score);
if(score>=90){
  printf("去食堂好好吃一顿");
}
return 0;
}

1.2 双分支结构
流程图语法

image-20210311185706416

image-20210311190314680

【实例】

使用代码实现下列描述的逻辑:

输入英语四级的成绩,如果英语四级考试通过的话,就继续考英语六级;如果四级都没过的话,还是好好回家背单词吧。

【解答】

#include <stdio.h>
int main(){
float score;
printf("请输入你的四级成绩:");
scanf("%f",&score);
if(score>=425){
  printf("真棒,继续考六级!!!");
}
else{
  printf("算了,还是好好回去背单词吧!!!");
}
return 0;
}

1.3 多分支结构
流程图语法

image-20210311185743198

image-20210311190329215

【实例】

使用代码实现下列描述的逻辑:

输入考试成绩,根据如下规则判断成绩等级

成绩范围等级
[ 90 , 100 ]优秀
[ 70 , 90 )良好
[ 60 , 70 )中等
[ 0 , 60 )一般

【解答】

#include <stdio.h>
int main(){
float score;
printf("请输入你的四级成绩:");
scanf("%f",&score);
if(score>=90){
  printf("等级为:优秀!!!");
}
else if(score>=70){
  printf("等级为:良好!!!");
}
else if(score>=60){
  printf("等级为:中等!!!");
}
else{
  printf("等级为:一般!!!");
}
return 0;
}

1.4 嵌套条件结构
流程图语法

image-20210311205341745

image-20210311205532954

【实例】

使用代码实现下列描述的逻辑:

输入性别和年龄,判断是否达到法定婚龄:

《中华人民共和国民法典》第一千零四十七条规定,结婚年龄,男不得早于二十二周岁,女不得早于二十周岁。

【解答】

在C语言中,字符串比较需要使用strcmp()函数,使用strcmp()函数需要引入头文件<string.h>

#include <stdio.h>
#include <string.h>
int main(){
    char sex[4];
    int age;
    printf("请输入你的性别:");
    scanf("%s",&sex);
    printf("请输入你的年龄:");
    scanf("%d",&age);
    if(strcmp(sex,"男")==0){
        if(age>=22){
            printf("该男生已经达到法定婚龄。");
        }
        else{
            printf("该男生没有达到法定婚龄。");
        }
    }
    else{
        if(age>=20){
            printf("该女生已经达到法定婚龄。");
        }
        else{
            printf("该女生没有达到法定婚龄。");
        }
    }
    return 0;
}

1.5 switch结构
流程图语法

image-20210312000205946

image-20210312001505643

【switch语法说明】

  • switch的表达式里面写判断依据,只能为整数字符类型;

  • case关键字后面写表达式(判断依据)可能的取值;

  • default关键字表示不满足所有取值的情况(错误取值);

  • break关键字指结束当前程序运行(也就是之后的程序不会被执行)。

【实例】使用代码实现下列描述的逻辑:

某同学想每天换换口味,于是决定周一、周三、周五在学校二楼食堂吃饭,周二、周四在三楼食堂吃饭,周末到校外吃饭。输入周几,查询出对应吃饭的地点。

【解答】

#include <stdio.h>
int main(){
    int week;
    printf("请输入你要查询的是周几(1-7)?");
    scanf("%d",&week);
    switch(week) {
        case 1:
        case 3:
        case 5:
            printf("去二楼食堂吃饭......");
            break;
        case 2:
        case 4:
            printf("去三楼食堂吃饭......");
            break;
        case 6:
        case 7:
            printf("去校外吃饭......");
            break;
        // 输入的信息不是1-7的其中一个的情况
        default:
            printf("你输入的信息有误,请重新输入......");
            break;
    }
    return 0;
}
1.6 多重分支结构和switch结构的使用场景
  • 多重if结构(多分支结构)可以用于所有情况的判断,但主要用于范围判断

  • switch结构主要用于等值判断(表达式的结果有固定取值,可以例举出来)。

2、循环结构

在生活中,我们经常会重复做一件事情,如:每天都会吃饭、睡觉等。在计算机中,我们经常也会处理一些重复的事情,如:输出100遍“Hello World”,直接使用输出语句的话是一个非常大的工作量。为了解决这个问题,C语言中中也提供了循环结构,来处理一些重复的事情。C语言循环结构主要包括以下两种:

  • while 循环

  • do-while循

  • for 循环

循环结构三件套

  • 初识值

  • 判断条件

  • 循环变量值的改变

2.1 while循环
流程图语法

image-20210315010600854

image-20210315010725969

whille循环特点:

  • 先判断,再执行循环操作;

  • 如果不满足条件,可能一次循环都不会执行;

  • 执行一次循环之后要更新循环变量,不然就会出现死循环。

【实例】输出100遍“Hello World”。

【解答】

#include <stdio.h>
int main(){
// 初始值
int i = 1;
// 循环条件
while(i<=100){
  printf("Hello World\n");
  // 循环变量改变
  i++;
}
return 0;
}

2.2 do-while循环
流程图语法

image-20210315011527895

image-20210315011655524

do-whille循环特点:

  • 不管其他,先执行一次循环操作,然后再判断。所以do-while循环最少都会执行一次。

  • 执行一次循环之后要更新循环变量,不然就会出现死循环。

  • 在do-while中,while(循环条件)之后要加上分号(;),即:

image-20210315111124899

【案例】 在控制台输出1-50

#include <stdio.h>
int main(){
// 初始值
int i = 1;
do{
  printf("%d\n",i);
  // 循环变量改变
  i++;
} while (i<=50);  // 循环变量改变
return 0;
}

2.3 for循环
流程图语法

image-20210315012301356

image-20210315012601984

【实例】

输出1-100之间所有的偶数

【解答】

#include <stdio.h>
int main(){
// 初始值、循环条件、循环变量改变均写在for的参数中
for(int i=2;i<=100;i+=2){
  printf("%d\n",i);
}
return 0;
}

2.4 循环结构综合案例

【实例】

编程计算1+2+3+...+100的值。

【解答】

  • 使用while实现

    #include <stdio.h>
    int main(){
        int i = 1;
        int sum = 0;  // 总和
        while(i<=100){
            sum += i;  // 每次循环得到的数据加入总和中
            i++;
        }
        // 循环结束之后输出结果
        printf("%d",sum);
        return 0;
    }

  • do-while循环

    #include <stdio.h>
    int main(){
        int i = 1;
        int sum = 0;  // 总和
        do{
            sum += i;  // 每次循环得到的数据加入总和中
            i++;
        } while(i<=100);
        // 循环结束之后输出结果
        printf("%d",sum);
        return 0;
    }

  • 使用for实现

    #include <stdio.h>
    int main(){
        int sum = 0;  // 总和
        for(int i=1;i<=100;i++){
            sum += i;  // 每次循环得到的数据加入总和中
        }
        // 循环结束之后输出结果
        printf("%d",sum);
        return 0;
    }

八、C语言函数

函数是一段具有特定功能、可重复使用的代码,它能够提高程序的模块化和代码的复用率。(编写一次可重复使用

1、无返回值函数的定义和调用

函数定义语法:

无返回值类型使用:void

void 函数名(形式参数列表) {
    // 函数体,即函数的实际操作
}

函数调用语法:

函数名(实际参数列表)

【实例1】

定义函数输出100遍“Hello World”

【解答】

#include <stdio.h>
​
​
// 函数定义
void print100(){
for(int i=1;i<=100;i++){
  printf("Hello World\n");
}
}
​
​
int main(){
// 函数调用
print100();
return 0;
}

【实例2】

定义函数输出指定遍数的“Hello World”

【解答】

#include <stdio.h>
​
​
// 函数定义
void printNum(int num){
for(int i=1;i<=num;i++){
  printf("Hello World\n");
}
}
​
​
int main(){
// 函数调用
printNum(10);
return 0;
}

2、有返回值函数返回值

函数除了可以在函数体中直接输出数据,还可以返回数据,称为函数的返回值。函数使用 return 语句返回值。

语法:

返回类型 函数名(参数列表) {
// 函数体,即函数的实际操作
return 变量;
}

接收函数返回的数据时,一般都使用变量进行接收,方便后面对接收到的数据进行二次处理。

变量名 = 函数名(实际参数列表)

【实例】

定义函数计算1-X之间所有奇数的和(X为一个正整数),并将结果返回。

【解答】

#include <stdio.h>
​
​
// 函数定义
int sumX(int X){
int sum = 0;
for(int i=1;i<=X;i+=2){
  sum += i;
}
return sum;
}
​
​
int main(){
// 函数调用
int sum = sumX(50);
printf("%d",sum);
return 0;
}

九、C语言的数组

1、定义数组

数据类型 数组名[数组长度];

2、初始化数组

2.1 定义后初始化
// 定义数组
int ages[5];
// 初始化数组
ages[0] = 18;
ages[1] = 19;
ages[2] = 21;
ages[3] = 20;
ages[4] = 18;
for(int i=0;i<5;i++){
    scanf("%d",&ages[i]);
}
2.2 定义时初始化
// 定义数组并初始化
int ages[5] = {18,19,20,21,23};
// 定义数组并初始化
// 3表示数组长度,10表示单个字符串的长度
char names[3][10] = {"张三","李四","王五"};

3、遍历数组

#include <stdio.h>
        
int main(){
    // 定义数组
    int ages[5];
    // 初始化数组
    printf("请输入数组元素:\n");
    for(int i=0;i<5;i++){
        scanf("%d",&ages[i]);
    }
    // 遍历
    printf("所有数组元素如下所示:\n");
    for(int i=0;i<5;i++){
        printf("%d\n",ages[i]);
    }
}

4、获取字符串长度

// sizeof(names):获取数组占用内存空间大小
int length = sizeof(names)/sizeof(names[0]);

十、C语言运算符

运算符指用于计算的符号。C语言中的运算符按照功能分为以下几类:

类型符号
赋值运算符=
算数运算符+ - * / %
复合赋值运算符+= -= *= /= %= ++ --
关系运算符> < >= <= == !=
逻辑运算符&& || !

1、赋值运算符

=

#include <stdio.h>
int main(){
    int number = 100;   // 将100赋值给number这个变量
    return 0;
}

2、算数运算符

+ - * / %(取余)

#include <stdio.h>
int main(){
    int a = 10;
    int b = 5;
    int add = a + b;  // 15
    int subtract = a - b;  // 5
    int ride = a * b;  // 50
    float except = (float)a / b;  // 2.000000
    int mod = a % b;  // (a/b)取余数
    return 0;
}

3、复合算数运算符

运算式等价式
a += 5a = a+5
a -= 5a = a-5
a *= 5a = a*5
a /= 5a = a/5
a %= 5a = a%5
a++a = a + 1
a--a = a - 1
#include <stdio.h>
int main(){
    int a = 5;
    a += 10;  // a = a + 10 = 5 + 10 = 15
    printf("%d",a);  // 15
    return 0;
}
#include <stdio.h>
int main(){
    int a = 50;
    a %= 7;  // a = a%7 = 50%7 = 1 ---> 50/7=7...1
    printf("%d",a);  // 1
    return 0;
}

++ :自增,变量自动+1

  • i++ 【先做其他操作,再运算(+1)】

  • ++i 【先运算(+1),再做其他操作】

-- : 自减,变量自动-1

  • i-- 【先做其他操作,再运算(-1)】

  • --i 【先运算(-1),再做其他操作】

【实例】读代码,得出i、j、k的值

【代码】

#include <stdio.h>
int main(){
    int i = 1;
    int j = i++;
    int k = --i;
    printf("%d\n",i);  // 1
    printf("%d\n",j);  // 1
    printf("%d",k);  // 1
    return 0;
}

4、比较运算符

> < >= <= ==(判断是否等于) !=(是否不等于)

  • 比较运算符用来比较两个值的关系,得到的结果是一个布尔类型(bool),要么是true,要么是false

#include <stdio.h>
int main(){
    printf("%d\n",3>5);  // 0
    printf("%d\n",7<=8);  // 1
    printf("%d\n",10/2==6);  // 0
    printf("%d",2*7 != 10);  // 1
    return 0;
}

5、逻辑运算符

在生活中我们经常会遇到多个条件判断 的情况,如:

《中华人民共和国民法典》第一千零四十七条规定:结婚年龄,男不得早于二十二周岁,女不得早于二十周岁。

这样如果需要判断一个人是否达到法定婚龄,就需要判断两个条件(性别、年龄),这个就要用到逻辑运算符:

运算符名称功能备注
&&多个条件条件同时满足所有条件都为true,结果为true,否则结果为false
||多个条件满足其中一个即可只要有一个条件为true,结果为true,否则结果为false
!条件取反条件为true,结果为false,否则结果为true
#include <stdio.h>
int main(){
    printf("%d\n",3>2 && 8!=5);  // 1(两个条件都为true)
    printf("%d\n",3>2 || 8==5);  // 1(一个条件为true即可)
    printf("%d",!(3>2));  // 0(true取反为false)
    return 0;
}

十一、关键字

1.typedef

类型定义 => 类型重命名

#include <stdio.h>
​
//将unsigned int 重命名为uint_32,所以unit_32也是一个类型名
typedef unsigned int unit_32;
​
int main() {
    //观察num1与num2,这两个变量的类型是一样的
    unsigned int num1 = 0;
    unit_32 num2 = 0;
    return 0;
}

2.static

static用来修饰变量和函数

1.修饰局部变量 称为静态局部变量

2.修饰全局变量 称为静态全局变量

3.修饰函数 称为静态函数

11.2.1修饰局部变量
#include <stdio.h>
​
void test() {
    //int a = 1; //输出全为2(放在栈区)
    static int a = 1;//输出为2到11
    /*static修饰局部变量的时候,
    局部变量出了作用域,不销毁的。
    本质上,static修饰局部变量的时候,
    改变了变量的存储位置(静态区)
    影响了变量的生命周期,生命周期变长,和程序的生命周期一样*/
    a++;
    printf("%d", a);
}
​
int main() {
    int i = 0;
    while (i<10)
    {
        test();
        i++;
    }
    return 0;
}
11.2.2修饰全局变量

作用域变小

#include <stdio.h>
​
​
static int m = 2020;
/*
static修饰全局变量的时候这个全局变量的外部链接属性变成内部链接属性,
其他源文件(.c)不能用extend来使用这个全局变量
*/
​
int main() {
    printf("%d", m);
    return 0;
}
11.2.3修饰函数
#include <stdio.h>
​
static int add(int x, int y) {
    return x + y;
}
/*
一个函数具有外部链接属性,
 static修饰函数的时候这个全局变量的外部链接属性变成内部链接属性,
其他源文件(.c)不能用extend来使用这个全局变量
*/
​
int main() {
    int x = 10;
    int y = 20;
    printf("%d",add(x,y));
    return 0;
}

3.register(寄存器)

一、register的作用 如果一个变量用register来修饰,则意味着该变量会作为一个寄存器变量,让该变量的访问速度达到最快。例如,一个程序逻辑中有一个很大的循环,循环中有几个变量要频繁进行操作,这些变量可以声明为register类型。

二、寄存器变量   寄存器变量是指一个变量直接引用寄存器,也就是对变量名的操作的结果是直接对寄存器进行访问。寄存器是CPU的“亲信”,CPU操作的每一个操作数和操作结果,都由寄存器来暂时保存,最后才写入内存或从内存中读出。也就是说,变量的值通常保存在内存中,CPU对变量进行读取是先将变量的值从内存中读取到寄存器中,再进行运算,运算完后将结果写回内存中。为什么要这么设计,不直接对变量的值在内存中进行运算,而要再借助于寄存器呢?这是由于考虑到性能的问题才这么设计的。在计算机系统中,包含很多种不同类型的存储器,如下图所示:

名称速度特点用途
静态存储器最快造价高,体积大,适合小容量的缓冲寄存器,缓冲
动态存储器较快造价低,体积小,适合大容量的缓冲内存

  在计算机中,CPU的运算速度最快,现在常用的CPU都已达3 GHz左右,而相对应的存储器速度却相对慢得多,访问速度最快的寄存器和缓冲,由于其体积较大,不适合大容量的缓冲使用,所以只能通过将二者结合的方式来提高效率。程序代码保存在内存中,当使用数据时,将其送到寄存器,让CPU来访问,使用完毕后,再送回内存保存。C语言允许使用寄存器保存变量的值,很明显这样能大大提高程序的执行速度。但是,寄存器的个数是有限的,X86也就是十几个,AMR最多才37个,我们不可能将全部的变量都声明为寄存器变量,因为其他代码也需要使用寄存器,同样,我们声明的寄存器变量也不一定直接保存在寄存器中,因为寄存器可能全部都被其他代码占用。编译器只能尽量把变量安排在寄存器中。

总结: 在使用寄存器变量时,请注意: (1)待声明为寄存器变量的类型应该是CPU寄存器所能接受的类型,寄存器变量是单个变量,变量长度应该小于等于寄存器长度。 (2)不能对寄存器变量使用取地址符“&”,因为该变量没有内存地址。 (3)尽量在大量、频繁操作时使用寄存器变量,且声明的变量个数应该尽量少。

#include <stdio.h>
​
int main() {
         //寄存器变量
         register int num = 10;
         //建议:将10存放入寄存中,最终决定在编译器
         return 0;
}

4.#define定义常量和宏

#include <stdio.h>
​
//#define定义常量
#define  num  100
//#define定义宏(宏是有数值的)
#define add(x,y) ((x)+(y))
/*
    #define 宏名(宏的参数)宏体
    宏的参数无数据leix
*/
/* int add(int x,int y){
            return(x+y);
 }*/
​
int main() {
    //打印#define定义常量
    printf("%d\n",num);
    int a = num;
    printf("%d\n",a);
    //打印#define定义宏
    int b = 10;
    int c = 20;
    int d = add(b, c);
    printf("%d", d);
    return 0;
}

十二、指针

1、概念

首先内存会划分为小的内存单元,每个内存单元都有一个编号,这个编号就被称为地址,我们把*地址也叫指针*

指针是一种特殊的变量,指向内存地址

  • 获取内存地址:

    • &:取地址符号

    • %p:内存地址的占位符

2、语法

数据类型 *变量名;
  • *:取值符号

int *p = &a;
  • p:指针p指向的内存地址

  • *p:指针p指向的内存地址对应的

  • &p:指针p对应的内存地址

img

【案例】

#include <stdio.h>
​
​
int main(){
    int a = 18;
    printf("a变量的内存地址:%p\n",&a);
    printf("a变量的内存地址对应的值:%d\n",a);
    // 指针
    int *p = &a;
    printf("指针p指向的地址:%p\n",p);
    printf("指针p指向的地址对应的值:%d\n",*p);
    printf("指针p的内存地址:%p\n",&p);
}

image-20240411134236030

#include <stdio.h>
​
int main() {
    int a = 10;//向指针申请4个字节,存储10
    //&a;//取地址操作符
    printf("%p\n",&a);
​
int* p = &a;
//p就是指针变量
*p = 20 ; //解引用操作符,意思就是通过p中存放的地址,找到p所指向的对象,*p就是p指向的对象
printf("%d\n", a);
return 0;
​
}

3、指针的大小

int main() {
    //指针变量的大小取决于地址的大小
    //32位平台下地址是32个bit位(即4个字节)
    //64位平台下地址是64个bit位(即8个字节)
    printf("%d\n", sizeof(char*));
    printf("%d\n", sizeof(short*));
    printf("%d\n", sizeof(int*));
    printf("%d\n", sizeof(double*));
    return 0;
}

十三、结构体

1.定义

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

结构体(struct)是一种用户自定义的数据类型,可以将多种单一的数据类型组合在一起。

结构体类似于Java中的,单一数据类型类似于类中的属性

2、语法

struct 结构体名称{
    数据类型1 属性名1,
    数据类型2 属性名2,
    ......
}

3、引用结构体

  • 创建结构体对象

    struct 结构体名称 对象名;
  • 引用结构体属性

    对象名.属性名

【案例】

#include <stdio.h>
#include <string.h> // 引入字符串相关的方法
​
​
// 定义结构体
struct Student{
    int id;
    char name[10];
    float score;
};
​
​
int main(){
    // 创建结构体对象
    struct Student stu;
    // 给结构体属性赋值
    stu.id = 1001;
    strcpy(stu.name,"张三");
    stu.score = 99.5;
    // 输出结构体属性
    printf("%d\n",stu.id);
    printf("%s\n",stu.name);
    printf("%f\n",stu.score);
}
#include <stdio.h>
​
//学生
struct Student {
    char name[20];
    int age; 
    char sex[10];
};
void print(struct Student* ps) {
    printf("%s %d %s\n", (*ps).name,(*ps).age,(*ps).sex);
​
    //->
    //指针变量->成员名
    printf("%s %d %s \n", ps->name, ps->age, ps->sex);
​
}
​
int main() {
    struct Student su ={
        "zhangsan",18,"男"
    };
    //结构体对象.对象名
    printf("%s %d %s\n", su.name, su.age, su.sex);
    print(&su);
    return 0;
}

  • 17
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值