自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

高效使用C語(yǔ)言

開(kāi)發(fā) 后端
const關(guān)鍵字的是constant的意思,即不變的,在C語(yǔ)言中作為關(guān)鍵字來(lái)告訴編譯器變量是不可修改的。

使用static關(guān)鍵字

static關(guān)鍵字有兩個(gè)作用,對(duì)于變量而言,表示該變量是一個(gè)靜態(tài)變量,放在數(shù)據(jù)段中,即使函數(shù)運(yùn)行結(jié)束,其變量也仍然存在。對(duì)于函數(shù)而言,表示該函數(shù)的作用域僅在該文件中,其他文件不可訪問(wèn),這樣有一個(gè)好處,就是當(dāng)該文件僅僅只被本文件中的函數(shù)調(diào)用時(shí),此時(shí)使用static關(guān)鍵字修飾可以避免其他函數(shù)因函數(shù)名相同而報(bào)錯(cuò),也就是當(dāng)使用該關(guān)鍵字修飾時(shí),即使兩個(gè)文件中的函數(shù)名完全相同,也不會(huì)報(bào)編譯錯(cuò)誤,例如下面有兩個(gè).c文件,分別是fun1.c和fun2.c。這兩個(gè)文件中有函數(shù)swap,函數(shù)名完全相同。這樣我們可以這樣使用static關(guān)鍵字:

//fun1.c
static void swap(int *a,int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}
//fun2.c
static void swap(int *a,int *b)
{
int temp;
temp=*a;
*a=*b;
*b=temp;
}

上面兩個(gè)文件中有完全一樣的函數(shù),函數(shù)只能在各自的文件中使用。

使用const關(guān)鍵字

const關(guān)鍵字的是constant的意思,即不變的,在C語(yǔ)言中作為關(guān)鍵字來(lái)告訴編譯器變量是不可修改的。

修飾變量

修飾普通變量

const用來(lái)修飾普通變量表示該變量的值不可修改,也就是只讀。比如現(xiàn)在定義一個(gè)const a=10,則a的值后面將不可修改。

const int a=10;  //初始化
a=20 //錯(cuò)誤,a的值不可修改

修飾指針變量

const用來(lái)修飾指針變量表示該指針的值不可修改,由于指針有兩個(gè)值可以修改,一個(gè)是指針的值,即指向的位置,另一個(gè)是指針指向的位置的值,為了區(qū)分這兩個(gè)值是否能修改,編譯器規(guī)定采用”就近原則“,即const修飾的是離const最近的。

int a=1,b=2; const int *p=&a;
//修飾的是int *,即表示指針解引不可修改,也就是指針指向的值不能修改,等價(jià)int const *p=&a;
*p=10;
//錯(cuò)誤,p指針指向的值不可修改
p=&b;
//正確,沒(méi)有改變p指向變量的值。
int * const q=&a;
//修飾的是指針q,即指針q指向的位置不可修改
q=&b;
//錯(cuò)誤,q指向的位置不可修改
*q=20;
//正確,沒(méi)有修改q指向的位置

修飾數(shù)組

const用來(lái)修飾數(shù)組表示該數(shù)組的所有值將不得修改,一般編譯器看到一個(gè)const數(shù)組會(huì)將該數(shù)組存放在代碼區(qū)中,也就是.text段,這樣該數(shù)組將是只讀數(shù)據(jù)。

const int a[4]={1,2,3,4};
a[1]=20; //錯(cuò)誤,a數(shù)組所有的元素均不可修改 a數(shù)組為read only,放在代碼段中

地址對(duì)齊

變量地址對(duì)齊

地址對(duì)齊是一個(gè)非常重要的概念,現(xiàn)代編譯器提高代碼的執(zhí)行速度(主要是配合cache),默認(rèn)將地址都按照4字節(jié)對(duì)齊,也即是一個(gè)字對(duì)齊。我們現(xiàn)在看下面一個(gè)結(jié)構(gòu)體:

struct test
{
char a;
int b;
}

如果不了解地址對(duì)齊概念的讀者可能會(huì)認(rèn)為上面的結(jié)構(gòu)體一共占1+4=5個(gè)字節(jié),實(shí)際上是占8個(gè)字節(jié),編譯器會(huì)按4字節(jié)對(duì)齊,由于a變量只占一個(gè)字節(jié),后面的b變量占4個(gè)字節(jié),如果只給a一個(gè)字節(jié)地址,編譯器會(huì)檢測(cè)到b變量的地址并不是按4字節(jié)對(duì)齊的,因此編譯器會(huì)默認(rèn)將分配給b變量的地址向后偏移3個(gè)字節(jié),這樣b變量的地址正好的四字節(jié)對(duì)齊。

#include <stdio.h>
struct test
{
char a;
int b;
};
int main(int argc, char **argv)
{
struct test a;
printf("size of struct test is =%d\n",sizeof(a));
return 0;
}



結(jié)構(gòu)體sshshishi’jshi’ji實(shí)際結(jié)構(gòu)

因此在定義一個(gè)結(jié)構(gòu)體時(shí)為了盡可能節(jié)約空間,必須考慮字節(jié)對(duì)齊問(wèn)題。下面我們來(lái)對(duì)比兩個(gè)結(jié)構(gòu)體:

#include <stdio.h>
struct A{
int a;
char b;
short c;
};
struct B{
char b;
int a;
short c;
};
int main(int argc, char **argv)
{
struct A st1;
struct B st2;
printf("size of st1 is=%d\n",sizeof(st1));
printf("size of st2 is=%d\n",sizeof(st2));
return 0;
}

運(yùn)行后結(jié)果如下:

兩個(gè)完全一樣的結(jié)構(gòu)體,僅僅只是變量存放的位置不同導(dǎo)致其最終所占的空間不同,這就是字節(jié)對(duì)齊帶來(lái)的結(jié)果。顯然結(jié)構(gòu)體A要節(jié)約內(nèi)存。

指針地址對(duì)齊

既然指針是變量,那是否可以對(duì)指針進(jìn)行位運(yùn)算呢?比如將指針的值最后一位清零:p&=(~(1)),理論上應(yīng)該是可行的,因?yàn)橹羔槺緛?lái)就是變量,但實(shí)際上編譯器不樂(lè)意了,它認(rèn)為這樣導(dǎo)致指針指向的地址太隨意了,沒(méi)有嚴(yán)格遵循比類型空間大小,這就導(dǎo)致指針沒(méi)辦法進(jìn)行位運(yùn)算操作,理論上位運(yùn)算和算術(shù)運(yùn)算是有等價(jià)關(guān)系的,因此也可以自己實(shí)現(xiàn)指針位運(yùn)算,這個(gè)在C++運(yùn)算符重載中可能比較方便,因此這里不詳細(xì)談指針的位運(yùn)算了。

責(zé)任編輯:龐桂玉 來(lái)源: C語(yǔ)言與C++編程
相關(guān)推薦

2013-01-14 09:29:04

2021-11-11 15:12:21

C語(yǔ)言線程代碼

2011-07-14 09:09:14

const

2010-01-11 09:40:02

C++語(yǔ)言

2011-05-13 17:25:34

C

2025-01-08 10:57:13

2011-07-05 16:57:53

C語(yǔ)言

2011-07-05 17:07:14

C語(yǔ)言

2014-08-01 15:16:05

SwiftC語(yǔ)言

2022-09-20 11:07:00

C語(yǔ)言X-MACRO技巧

2023-04-20 17:26:40

FreeDOSC 語(yǔ)言

2010-01-18 17:14:50

C++語(yǔ)言

2015-05-25 15:31:56

C語(yǔ)言學(xué)習(xí)和使用 C 語(yǔ)言

2017-05-05 09:45:13

編程語(yǔ)言學(xué)習(xí)代碼

2023-08-08 13:51:13

Gherkin開(kāi)發(fā)

2025-02-14 08:13:05

AI技術(shù)開(kāi)發(fā)

2010-01-15 17:38:37

C++語(yǔ)言

2024-04-10 12:56:00

C#批量插入開(kāi)發(fā)

2021-11-08 23:09:07

Go排序數(shù)據(jù)

2021-03-08 07:46:53

Git開(kāi)源控制系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)