当前位置: 首页 > article >正文

Linux第一课:c语言 学习记录day10

六、函数

8、string函数族

3、strcat

#inlcude <string.h>

        char *strcat(char *dest, const char *src);

功能:用于字符串拼接

参数:dest:目标字符串首地址

                src:原字符串首地址

返回值:目标字符串首地址

示例:

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

int main(int argc, char const *argv[])
{
    char s[32] = "world";
    char a[32] = "hello";
    strcat (s, a);
    printf ("%s\n", s);
    return 0;
}

#inlcude <string.h>

        char *strcat(char *dest, const char *src);

功能:用于字符串拼接

参数:dest:目标字符串首地址

                src:原字符串首地址

                n:原字符串拼接个数

返回值:目标字符串首地址

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

int main(int argc, char const *argv[])
{
    char s[32] = "world";
    char a[32] = "hello";
    strncat (s, a, 3);
    printf ("%s\n", s);
    return 0;
}

4、strcmp

#include <string.h>

int strcmp(const char *s1, const char *s2);

 功能:用于字符串比较

参数:s1、s2 用于比较字符串首地址

返回值:

        从字符串首个字符开始比较字符ASCII码的大小,如果相等继续比较第二个字符

        s1 > s2        ASCII:s1 - s2

        s1 == s2        0

        s1 < s2        ASCII:s1 - s2

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

int main(int argc, char const *argv[])
{
    char a[3] = "aa";
    char b[3] = "bb";
    char s[3] = "aa";
    
    int ret1 = strcmp (a, s);
    int ret2 = strcmp (a, b);
    int ret3 = strcmp (b, a);
    printf ("ret1 = %d\n", ret1);
    printf ("ret2 = %d\n", ret2);
    printf ("ret3 = %d\n", ret3);
    return 0;
}

 

#include <string.h>

int strncmp(const char *s1, const char *s2, size_t n);

 功能:用于字符串比较

参数:s1、s2 用于比较字符串首地址

                n:两个字符串比较的前n位

返回值:

        从字符串首个字符开始比较字符ASCII码的大小,如果相等继续比较第二个字符

        s1 > s2        ASCII:s1 - s2

        s1 == s2        0

        s1 < s2        ASCII:s1 - s2

七、结构体

1、定义

用户自定义的数据类型,在结构体中可以包含若干个成员变量(数据类型可以不同也可以相同),使这些数据项组合起来反应某一个信息

2、格式

struct 结构体名        // 用户自己定义的数据类型

{
        数据类型 成员变量 1;

        数据类型 成员变量 2;

        ……

        数据类型 成员变量 n;        // 描述信息的变量

}

3、结构体变量

1、概念

        通过结构体类型定义的变量

2、格式

        struct 结构体名 变量名;

1、先定义结构体,再定义结构体变量

struct 结构体名

{
       成员变量 1;

};

struct 结构体名 变量名;

#include <stdio.h>

struct student
{
    char name[32];
    int id;
    int age;
};

int main(int argc, char const *argv[])
{
    struct student stu;
    return 0;
}

此时stu为局部变量

 2、定于结构体的同时,定义结构体变量

struct 结构体名

{

        成员变量

}变量名;

#include <stdio.h>

struct student
{
    char name[32];
    int id;
    int age;
}stu;

int main(int argc, char const *argv[])
{
    return 0;
}

此时stu为全局变量

3、缺省结构体名定义结构体变量

struct

{

        成员变量;

}变量名;

4、赋值

1、定义变量的同时,直接用{}赋值

#include <stdio.h>

struct student
{
    char name[32];
    int id;
    int age;
};

int main(int argc, char const *argv[])
{
    struct student stu = {"Zhangsan", 123456, 18};    // 一一对应
    return 0;
}

2、定义变量时,未初始化,然后对变量单独赋值

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

struct student
{
    char name[32];
    int id;
    int age;
};

int main(int argc, char const *argv[])
{
    struct student stu;
    stu.age = 18;
    stu.id = 1;
    strcpy(stu.name, "Zhangsan");
    return 0;
}

3、点等法赋值

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

struct student
{
    char name[32];
    int id;
    int age;
};

int main(int argc, char const *argv[])
{
    struct student stu = {
        .age = 34,
        .id = 1234,
        .name = "Zhangsan",
    };
    return 0;
}

5、访问

通过 . 访问:结构体变量名. 成员变量名

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

struct student
{
    char name[32];
    int id;
    int age;
};

int main(int argc, char const *argv[])
{
    struct student stu;
    scanf("%s %d %d", stu.name, &stu.id, &stu.age);
    printf("%s %d %d\n", stu.name, stu.id, stu.age);
    return 0;
}

6、重定义

        typedef

typedef int int_num;

int a; == int_num a;

typedef int* int_p;

int *p = &a; == int_p p = &a;

1、定义结构体的同时重定义

typedef struct student

{

        char name[32];

        int id;

        int age;

}STU;        // typedef struct student STU

struct student stu; == STU stu;

2、先定义结构体,然后重定义

struct student

{

        char name[32];

        int id;

        int age;

};

typedef struct student STU;

7、结构体数组

1、概念

结构体类型相同的变量组成的数组

2、格式

1、定义结构体的同时,定义结构体数组

struct student

{
        int id;

        int age;

} stu[3];

2、先定义结构体,然后定义结构体数组

struct student

{
        int id;

        int age;

} ;

struct student stu[3];

3、初始化

1、定义结构体数组同时赋值
#include <stdio.h>

struct student
{
    char name[32];
    int id;
    int age;
} stu[3] = {
    {"zhangsan", 1, 45},    // 第一个人的信息
    {"lisi", 2, 32},
    {"wangwu", 3, 123},
};

int main(int argc, char const *argv[])
{
    return 0;
}
2、先定义结构体数组,再对结构体数组的每一个元素分别赋值
struct student
{
    char name[32];
    int id;
    int age;
} stu[3];

strcpy(stu[0].name, "zhangsan");
stu[0].id = 2;

stu[1].age = 12;

4、结构体数组的大小

元素个数 * 结构体类型大小

sizeof(结构体数组名);

5、结构体数组输入输出(for循环)

#include <stdio.h>

struct student
{
    char name[32];
    int id;
    int age;
} stu[3];

int main(int argc, char const *argv[])
{
    for (int i = 0; i < 3; i++)
    {
        scanf("%s %d %d", stu[i].name, &stu[i].id, &stu[i].age);
    }
    for (int i = 0; i < 3; i++)
    {
        printf("%s %d %d", stu[i].name, stu[i].id, stu[i].age);
    }
    return 0;
}

8、结构体指针

1、概念

指向结构体的指针

2、格式

struct 结构体名* 指针变量名

示例:注意数据类型匹配

#include <stdio.h>

struct student
{
    int id;
    int age;
} stu1, stu2;

struct worker
{
    int id;
    int age;
} w1, w2;

int main(int argc, char const *argv[])
{
    struct student* p = &stu1;
    struct student* q = &w1;    // 结构体类型不匹配
    return 0;
}

3、赋值

格式:结构体指针变量名->成员变量名

                (*结构体指针变量名).成员变量

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

struct student
{
    int id;
    int age;
} stu1;

int main(int argc, char const *argv[])
{
    struct student* p = &stu1;
    p -> id = 1;
    (*p).age = 18;
    return 0;
}

4、结构体指针大小

本质时指针,8字节

总结

1、不能把结构体类型变量作为整体引用,只能对结构体类型变量中的成员变量分别引用

2、如果成员变量本身属于另一个结构体类型,用若干个成员运算符一级一级找到你想要的成员变量

3、可以把成员变量当成普通变量运算

4、在数组中,数组之不能整体的彼此赋值,结构体变量可以整体相互赋值

int a[3] = {};

int  b[3] = {1, 2, 3};

a = b;        // 错误,数组名不能为左值

a [0] = b[0];        // 正确,单个的元素可以

struct student

{

        int id;

        int age;

} stu1, stu2;

int main ()

{

        stu1.id = 10;

        stu1.age = 20;

        stu2 = stu1;        // 正确,结构体变量可以整体相互赋值

        return 0;

}

9、结构体大小

sizeof(struct 结构体名);        // 结构体类型大小

#include <stdio.h>

struct stu
{
    char a;
    short b;
    int y;
    char w;
};

int main(int argc, char const *argv[])
{
    printf("%d\n", sizeof(struct stu));
    return 0;
}

结构体大小遵循字节对齐原则

1、字节对齐

        在实际使用中,访问特定数据类型变量时需要在特定的内存起始地址进行访问,这就需要各种数据类型按照一定的规则在空间上进行排列,而不是顺序地一个接一个地存放,这就是字节对齐

2、字节对齐原则

        a、在64位系统下默认的value值为8字节,判断结构体类型中最大成员变量的字节大小,和默认的value值进行比较,按小的数进行对齐

        b、结构体成员进行对齐时遵循地址偏移量是成员类型的整数倍

        c、​​​​​​​结构体成员按顺序进行存储,如果不满足以上条件时,需要填充空字节

3、为什么要进行字节对齐?

        a、​​​​​​​平台原因:不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。(提高程序的移植性)

        b、​​​​​​​性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

        c、​​​​​​​内存原因:在设计结构体时,通过对齐规则尽可能优化结构体的空间大小至最小空间

示例:

struct S

{

        int a;        // 4

        char b;        // 1

        short c;        // 2

        double d;        // 8

};

第一步:找出成员变量的最大字节数,让其与编译器的默认对齐数进行比较,取较小的值作为该成员变量的对齐数,相等就开8字节

第二步:根据每个成员对应的对齐数画出他们在内存中的相对位置

第一个是int类型的,从第0地址开始偏移,0是4的0倍,第0-3地址给int;第二个是char类型的,从第4字地址开始偏移,4是1的4倍,第4地址给char;第三个是short类型,从第5地址开始偏移,5不是2的倍数,所以给null,然后看第6地址,6是2的倍数,所以第6-7地址给short;第四个是double类型的,从第8地址开始偏移,8是8的1倍,所以第8-15地址给double

最终统计一共以8为对齐数,开两行,0-15一共16个字节

如果最后再多加一个char类型,那就再多开一行,第16地址给char,后面17-23地址全部都是null


http://www.kler.cn/a/501597.html

相关文章:

  • AWS简介
  • 每年一问:Java日期格式化中周所在年引发的bug
  • 香港云服务器的ip可以更换的吗?
  • PMP–一、二、三模、冲刺–分类–7.成本管理
  • Vue 开发者的 React 实战指南:快速入门与思维转换
  • 从项目代码看 React:State 和 Props 的区别及应用场景实例讲解
  • iOS - Objective-C语言的动态性
  • MacOS15 bash 终端怎么使用网络代理
  • 《拉依达的嵌入式\驱动面试宝典》—操作系统篇(五)
  • Kotlin 极简小抄 P5(异常、异常处理、自定义异常)
  • 三天学完微服务其二
  • 【江协STM32】10-4/5 I2C通信外设、硬件I2C读写MPU6050
  • Web3 重塑隐私保护:构建数字安全新防线
  • Flutter:吸顶效果
  • git打补丁
  • 010:传统计算机视觉之大津算法初探
  • centos7.6 安装nacos 2.0.4与恢复nacos的mysql
  • 【Ubuntu与Linux操作系统:八、Ubuntu桌面应用】
  • 因泰立科技激光车检器,高速公路的精准流量统计专家
  • ubuntu编译ijkplayer,支持rmvb以及mkv