C语言基础(七)

关键字 volatile

可变的,编译器不会做优化,每次都是从内存中重新读取数据
正常情况下:内存——>寄存器——>cpu
volatile:内存——>cpu

二维数组

二维数组的数组名是数组第一个元素的首地址,也就是arr=&arr[0]
arr[0]是第二位的数组名,也就是arr[0] == &arr[0][0]
arr[0][0]是元素了,就没有地址啥事了
一重指针和二维数组匹配

int *p = arr[0];
p++;//p = arr[0][1];

数组指针和二维数组匹配

int (*p)[2]= arr;//不行
int (*p1)[3] = arr;//合适

指针数组和二维数组匹配

int *p[2] = {arr[0],arr[1]};//== p[0]=arr[0]

二重指针

指向的对象是一个指针(int *),该指针指向一个int型数据

int **p = arr;不兼容的指针类型初始化不行;
二维数组名与二重指针压根不匹配
int **p,*p1;//定义指针,可以理解== int *p,p1;
p=&p1;//绑定

非法地址访问

int *a 
a=(int *)0x123 //(int *)把数值0x123强制转化为地址 
*a=xxx 
不能这样使用非法地址

结构体struct

结构体是一种数据结构,解决了数组里不能存放多种类型的数据这种缺陷
数据结构:基本数据结构(int、float),数组是一种数据结构(缺点:元素单一)
结构体的关键字:struct infor标识符,struct infor 是个类型
.的优先级比&高

struct infor        // struct infor 是标识符,必须整体使用
{
    char name[50];  // (元素)成员变量(属性)
    char is_male;
    int age;
};              // 分号坚决不能少

struct 
//struct data
{
    int a;
    float b;
    char c;
}s;  // 这个S是变量名的意思;定义类型的同时给出了结构体的变量名

typedef struct str5
{
    int a;
    char b;
}ST, *p_ST;      // ST是struct str5的类型名,p_ST是struct str5 *类型的别名
ST a;//结构体类型的变量a
p_ST p;//指向结构体变量的指针p

定义一个类型,不占空间,声明该类型的变量时才分配空间。
typedef struct infor S; //重定义类型名

初始化
完全初始化

S s1={“name”,’0’,3};

部分初始化

S s2={“name”}; 
S s3={.age=3}; 
运算符(.)是专用于结构体变量访问个元素

注意:
S s3 = {1, 2, 3};//错误:由于第一个成员是字符串类型,所以系统会读取数据到遇到’\0’赋值给.name成员

结构体指针

结构体指针, 野指针

struct st *p;
struct st s;
p = &s;

结构体数组

#include <stdio.h>

struct st
{
    int a;
    float b;
    char c;
}; // 结构体类型
void set_value_func(struct st arr[], int lenth)
{
    int i = 0;

    for (i=0; i<lenth; i++)
    {
        scanf("%d", &arr[i].a);
        scanf("%f", &arr[i].b);
        scanf("%d", &arr[i].c);
    }
}

void show_infor_func(struct st arr[], int lenth)
{
    int i = 0;
    for (i=0; i<lenth; i++)
    {
        printf("%d %.2f %d\n", arr[i].a, arr[i].b, arr[i].c);
    }
}

int main(void)
{   
    struct st arr[3];
    set_value_func(arr, 3);
    show_infor_func(arr, 3);
    return 0;
}
结构体里.号的实质

&s类型是struct st *

int *p_a = (int *)&s;
printf("*p_a = %d.\n", *p_a);
float *p_b = (float *)((char *)&s+4); // sizeof(char) * 4 = 4字节a
分析:地址值转化为数字,加上几就是几

float *p_b = (float *)((long)&s+4);   // overlap
printf("*p_b = %.2f.\n", *p_b);
char *p_c = (char *)((char *)&s+8);
printf("*p_c = %d.\n", *p_c);

struct st s1;
相同结构体变量之间可以互相赋值.在C++里有个称呼叫做:赋值构造
s1 = s;

结构体的字节对齐规则

struct str1      // 7
{
    int a;       // 4
    char b;      // 1 + 1
    short c;     // 2
}s1; // 8

struct str2
{
    char a;     // 1
    char b;     // 1
            // + 2  
    int c;      // 4
}s2; // 8

struct str3         // 6
{
    int a;
    char b;
    char c;
            // + 2
}s3;  // 8

struct str4     // 10
{
    struct str1 s;  // 8
    char a;         // 1 + 1
    short b;       
}s4; // 12     

typedef struct str5     // 5
{
    int a;
    char b;
}ST, *p_ST;      // ST是struct str5的类型名,p_ST是struct str5 *类型的别名

struct str6     // 5
{
    char a;
    int b;
}S, *p = &S;        // S是struct str6的变量名, p是此结构体的指针变量名。

//默认是4字节对齐,最大的基本数据类型和这个默认值要相比较,取其小
struct str7
{
    char ab;
    int a[2];
//  char b;
};

1、 结构体变量的地址是从4字节对齐的未知开始(048、C)
2、各成员在结构体里自身要对齐;
3、成员之间不满足自身对齐,得填充(padding)
4、满足结构体自身对齐的最小倍数
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值