c語言基礎(十)

內存

內存:配置的內存是物理器件,程序運行起來是在虛擬內存中運行。
swap:虛擬內存,真實內存的1-1.5倍
虛擬內存分段:棧段、堆段、代碼段(.text) 、roread段、文件映射區、內核區、數據段、.bss段

(1)存儲類

有一些關鍵字專門用於描述:變量存儲的地方(內存)
棧,如:棧上變量儲存關鍵字auto。1、通常情況下,用佔的地方,普通變量。2、函數傳參,函數參數相當於局部變量。
堆,malloc+free的那一幫子函數,表示變量在堆空間。
代碼段:函數,char *p=“12345”可能在只讀段.
roread段:const修飾的變量
文件映射區:當你進程打開一個文件,就在內存中有了一個副本,更新或者操作l這個文件,保存一下,就保存在了你的硬盤上。
內核區:各自的進程彼此之間,是看不見,獨想你的整個虛擬內存。所以,各自的進程裏,都有一個內核區。
data段:1、static修飾的顯式初始化爲非0的局部變量,2、顯式初始化爲非0的全局變量。
.bss段:1、static修飾的初始化爲0或者不初始化的局部變量2、初始化爲0或者不初始化的全局變量。
static:修飾局部變量每次調用時,保留上一次的運行結果
register關鍵字,修飾的變量,儘可能存在寄存器裏。
volatile關鍵字,見memory.c
restrict 專用於修飾指針.

(2)作用域

花括號{}裏面的變量,只能在裏定義時,到你的花括號結束有效。
定義和聲明有時候不會嚴格區分

(3)生命週期

這個變量從誕生到消亡的一個過程。
1、棧變量:作用域(花括號內,從你定義的那一刻直到花括號結束),函數結束就消亡了,臨時的生命。
2、堆變量: 作用域(花括號內,從你定義的那一刻直到花括號結束),伴隨整個程序,直到程序結束
3、代碼段:放的是函數,伴隨整個程序
4、只讀變量:普通變量的作用域,伴隨整個程序。
5、data段變量:作用域:定義時,之後直到程序結束都可以用(1、全局,2、局部),伴隨整個程序。
6、.bss段
這裏寫圖片描述


(4)鏈接屬性

extern專用於聲明。
我們很多很多文件(.c)就組成一個工程。linux操作系統,是由2萬多個.c文件組成.
c語言編譯鏈接過程:所有的.c文件,編譯成了.o的目標文件(2進制),彼此是孤立的,接着就是鏈接器,鏈接起來。所有的.o的目標文件都對應一個相應的符號。所有的符號進行鏈接。
在os下:裏寫好的可執行文件,是別人給你寫好了一段對C語言引導作用代碼,加載到相應的內存。位置(地址)無關碼和位置有關碼?
data段和.bss:在你的C語言(宏替換之前)運行之前,(引導乾的)你的.data段已經被賦值,.bss段被清0.
全局變量:鏈接屬性是外鏈接(文件級別),而加了static修飾的全局變量就變成了,本文件鏈接屬性(內鏈接)
函數:默認是外鏈接,static修飾的函數變成了內鏈接,只在本文件起作用。

共用體

共用體表示幾個變量共用一個內存位置,在不同的時間保存不同的數據類型和不同長度的變量。在union中,所有的共用體成員共用一個空間,並且同一時間只能儲存其中一個成員變量的值。
共用體,聯合體,聯合數據類型,和struct類似的一種數組類型,可以存放不同類型的數據,但是和struct又有很大的區別。union裏面的成員變量公用一個內存首地址地址。各成員的解析按照你打印的方式或者讀取的方式。
共用體是一種數據結構。
共用體內成員的地址一樣,它的大小爲共用體內最大成員的大小
共用體可以用於測試大小端存儲
union的幾個特性:

(1)共用體的長度由他最大的那個成員變量的長度來決定。

#include<stdio.h>

union data{
    int a;//4個字節
    char b;//2個字節
    float c;//4個字節
}u;

int main(void){
    printf("sizeof(u)=%d\n",sizeof(u));
    return 0;
}

這裏寫圖片描述

(2)共用體公用一個內存首地址

#include<stdio.h>

union data{
    int a;
    char b;
    float c;
}u;

int main(void){
    printf("a的地址爲=%p\n",&u.a);
    printf("b的地址爲=%p\n",&u.b);
    printf("c的地址爲=%p\n",&u.c);
    return 0;
}

如圖 變量a和變量c公用一個內存首地址:
這裏寫圖片描述

(3)共用體的解析方式

#include<stdio.h>

union data{
    int a;
    char b;
    float c;
}u;

int main(void){
    u.a = 4;
    printf("a=%d\n",u.a);
    printf("b=%d\n",u.b);
    printf("c=%f\n",u.c);
    return 0;
}

這裏寫圖片描述

共用體的應用

(大小端big-endian、little-endian)用來測試是大端存儲還是小端存儲
小端:較高的有效字節存放在較高的的存儲器地址,較低的有效字節存放在較低的存儲器地址。
大端:較高的有效字節存放在較低的存儲器地址,較低的有效字節存放在較高的存儲器地址。

#include<stdio.h>

union data{
    int a;
    char b;
}u;

int main(void){
    u.a = 4;//給a賦值爲4,如果用b解析是4的話,證明是小端存儲的。如果是0的話,低字節沒有數據,就說明是大端存儲
    printf("a=%d\n",u.a);
    printf("b=%d\n",u.b);
    return 0;
}

結果如圖
這裏寫圖片描述
由此可得出我的電腦三小端存儲

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章