C语言里面数组,指针,结构体的一些见解

C语言里面数组,指针,结构体的一些见解

1. 数组

1.1 数组概念

在c语言里面有数组这个概念, 就像传统的int a[5], char c[10] 其中a和c都为数组(a为int类型的数组, c为char类型的数组), 数组和普通变量的区别就在于,他是一段连续的区域,在虚拟地址上是连续的,我们可以通过下标其中任意一个元素,第i个元素的地址为a0 + (i-1)*sizeof(T)(其中a0为数组收地址,T为数组的类型)。

2. 指针

2.1 指针概念

c语言里面有指针这个概念,这也是c语言本身很重要的一个东西,个人认为指针几乎是c语言的灵魂,指针的存在也让c语言成为了一门能够写底层系统的语言。对于指针, 我们也可以把他理解为一个变量, 指针本身也具有自己的内存,大小一般都是比其类型本身要来得大。
指针可以把变量的地址赋值给它类似, 类似下面的代码:

    int  x = 1; 
    int *p;
    p = &x

我们对指针p解引用就能得到对应x的值1。

2.2 指针类型:

指针有分一级指针和多级指针,但实际运用就一级指针和二级指针,一级指针就是普通的指针(类似int *p),二级指针其实就是指向指针的指针(类似int **p, 对p取解引用就对应得到一级指针,在解引用就是对应地址存储的值)。

2.3 指针作用:

指针,主要是为了用来操作变量和内存的,这里的内存主要指已经分配好的内存。好比一个数组,我们可以通过将一个指针指向一个数组的首地址,那么变可以通过这个指针来遍历这个数组和改变数组的值。指针所指向的位置,就是该数组对应元素的地址。

结构体

3.1 结构体概念

在c语言中,结构体也是类似像普通变量和数组那样的另一类变量,用struct关键字来修饰结构体变量,例如:

struct student{
    int id;
    char sex;
    char *name;
    float weight;
}

上述代码就定义了一个student类型的结构体,其中包含了id, sex, name, weight 4种属性,这四个属性构成了一个整体。之所以要引入结构体这个东西,个人认为是为了更好管理对象,强调整体意识。 虽然我们也可以直接用分开的定义这4个变量,在我们自己的意识里面来让它成为一个整体,但这样编程的话会大大增加了很多操作的难度。
当我们定义了一个结构体变量时(或用指针指向一个结构体变量),我们就可以通过这个结构体变量或者指针来访问结构体中的成员。以上述student结构体为例。

struct student stu;  // 定义一个类型为 student 的结构体变量 stu;
printf("%d %c %s %f\n", stu.id, stu.sex, stu.name, stu.weight);
struct student *p = &stu;  // 定义一个类型为 student 的结构体指针变量 p;
printf("%d %c %s %f\n", p->id, p->sex, p->name, p->weight);

有一点需要注意的是,我们定义了结构体,那么在访问该变量前,都需要对结构体进行赋值,或者做一些初始化,否则访问结构成员变量时遇到的值往往都会出乎我们意料,甚至会产生很难查找的bug, 上诉结构体如果不赋值或者初始化,那么打印student 成员变量的值会出现很情况的情况。
在这里插入图片描述
从上诉运行情况可以看到id的值为0, sex为(null), name为空, weight则为一个很奇怪的值。

3.2 结构体内存模型

结构体里面有个很重要的知识点就是结构体对齐。我们可以看以下两个结构体结构

struct student{
    char a;
    char b;
    int c;
}
printf("%d\n", sizeof(student));

我们运行上面程序可以看出,printf输出的值为: 8;
然后我们再看下面的程序

struct student{
    char a;
    int c;
    char b;
}
printf("%d\n", sizeof(student));

printf输出的值为: 12
可以发现,这两个结构体里面的成员变量是完全一样的,唯一不同的就是结构体里面成员变量位置排列是不相同的。
之所以会出现这种情况,主要和结构体的内存模型有关。结构体有个概念——偏移量。偏移量指的是结构体变量中成员的地址和结构体变量地址的差。结构体访问其成员变量都是以偏移量为准来进行查找内存的。结构体的偏移量为结构体中各个成员变量中字节最大的那个,即:
o f f s e t = m a x ( s i z e o f ( T ) ) offset = max(sizeof(T)) offset=max(sizeof(T))
其中T为成员变量的类型。
为什么要有偏移量?主要原因是为了可以较快的访问结构体内的成员变量。按道理说,这个结构体的大小应该为6字节。然而上面两种情况都不为6字节。原因就在于为了让结构体访问其成员变量更加方便。假设不设置内存对齐,那么结构体要访问成员变量c,就得扫3次,即访问3次内存。而用力内存对齐后,那么访问成员变量c只需要一次访问内存即可。其实就是牺牲了内存,换来了速度上的优势。

你可能感兴趣的:(语言类)