c語言基礎知識

audience_fzn發表於2018-08-02

一、常量變數

1.常見的一些資料型別

int 4位元組,short 2位元組,long 4位元組(跟平臺有關,可能是4,也可能是8),longlong 8位元組, char 1位元組,float 4位元組,double 8位元組

2.字串

是由雙引號引起來的一串字元,以/0作為結束標誌。

‘/0’不是字串的內容,只是一個結束標誌,所以strlen時不會求‘\0’的長度

char arr[] = {'h','e','h','e'};

printf("%s", arr); //%s是以字串形式輸出,遇到‘/0’停止,但是arr[]陣列中沒有‘/0’,所以就會繼續訪問後面的內容,知道遇到‘/0’為止,所以會訪問記憶體出錯

3.const關鍵字

  • 在c語言中:當const修飾一個識別符號的時候,這各識別符號依然是一個變數,只是具有常屬性,不能被直接改變
  • 在C++中,const修飾一個識別符號時,編譯器會自動將其設定未暫存器變數,當使用指標取修改時,改的時記憶體裡面的值,所以暫存器中儲存的值仍然不會被改變
        const int sz = 10;
	int * p = (int*)&sz;
	*p = 20;
	printf("%d", sz);   //10
       	volatile const int sz = 10;
	int * p = (int*)&sz;
	*p = 20;
	printf("%d", sz);//20

volatile:保證記憶體的可見性,讓變數的每次取值都去記憶體裡去取,這樣就可以改變sz的值了

4.define:是一個指令,並不是一個關鍵字

#define PAI 3.14

5.列舉:enum關鍵字,列舉常量的值會依次增加,如果不指定就從0開始加,如果指定,就從指定值開始增加

enum Sex
{
	MALE,
	FEMALE,
	SECRET
};

enum Sex
{
	MALE=20,
	FEMALE,
	SECRET
};

6.register關鍵字:會將變數儲存在暫存器內,不能對其進行&操作,因為編址是針對記憶體的。register只是一個建議。

7.fflush(stdin)/fflush(stdout):清空輸入輸出緩衝區

8.static關鍵字:

區域性變數:改變其生命週期(儲存位置:棧->靜態區)

全域性變數:改變其連結屬性(作用域)

9.初始化:

全域性變數:預設初始化為0

區域性變數:必須自己初始化(隨機值)

10:printf()函式返回值:返回列印字元的個數

        int i = 43;
	printf("%d", printf("%d", printf("%d", i)));

i是43,其返回值是2,外層printf()輸出的值為2,輸出2後返回值為1,所以最外層的printf()返回1,即4321;

二、分支語句

1.if語句:else語句總是跟在其之前未配對的最近的if匹配

if語句書寫規範:

  • bool和零值比較:if(flag),if(!flag),不能使用if(flag==TRUE)/if(flag==FALSE),flag是個整數,可以被賦值為2,3,等如何非0數字來表示真,而TRUE,FLASE只有一個固定的值
  • 整形變數和零值比較:if(n==0),if(n!=0)
  • 指標變數和零值比較:if(p==NULL),if(p!=NULL)
    • 指標使用時要注意:1.初始化為NULL 2.使用之前判空
        int *p = NULL;
	if (p != NULL)
	{
		*p = 20;
	}
  • 浮點數與零值比較:#define EXP 0.0000000001 ,if((f>-EXP)&&(f<EXP))

2.switch語句:switch,case語句中,case後必須為整形的常量表示式。

switch語句中,我們沒有辦法實現分支,搭配break才能實現真正的分支。

最好在最後加上default語句,甚至可以在後邊也加一個break

三、迴圈語句

1.break與continue:

whlie語句中:break:永久跳出迴圈,continue:終止本次迴圈,跳到while語句的判斷部分

for語句中:break:永久跳出迴圈,continue:跳出迴圈體,到調整部分

2.while語句:

	int i = 1;
	while (i <= 10)
	{
		if (i == 5)
			break;
		printf("%d", i);
		i = i + 1;
	}

//輸出1 2 3 4

int i = 1;
while (i <= 10)
{
    if (i == 5)
      continue;
    printf("%d", i);
    i = i + 1;
}

//輸出1 2 3 4 在i=i+1,之前就跳出迴圈了所以i一直為5,然後陷入死迴圈

int i = 1;
while (i <= 10)
{
    i = i + 1;
    if (i == 5)
      continue;
    printf("%d", i);
}

//輸出 2 3 4 6 7 8 9 10 11,沒有5

 

3.for迴圈的一些變形

        int i = 0;
	int j = 0;
	for (; i < 10; i++)
	{
		for (; j < 10; j++)
		{
			printf("hehe\n");
		}
	}

//輸出10個“hehe”,i=0進入迴圈直到j=10,共十次,下次i=1進來時,j=10不進入迴圈

注:程式設計時要特別注意不要將==誤寫為=;

for (i=0,j=0; i < 2,j<5; i++,j++)
{
    printf("hehe\n");
}

//輸出5個“hehe”,i<2,j<5;是一個逗號表示式,逗號表示式從左向右求值,結果為最後一個表示式的值

for (i = 0, j = -1; j = 0; i++, j++)
{
    j++;
    printf("hehe\n");
}

//不輸出,k=0,給k賦值為0,0為假,不進入迴圈

for (;;)
{
    printf("hehe\n");}

//判斷條件為空,預設為真,陷入死迴圈

for (i=0,j=0;i+j<10;++i,j++)
{
    printf("hehe\n");
}

//輸出五個hehe

4.迴圈效率

在多重迴圈中,如果有可能,要將最長的迴圈放在內層,最短的迴圈放在外層,以減少CPU跨切迴圈層的次數

迴圈體內部存在邏輯判斷,並且次數很大的,宜將邏輯判斷放在迴圈體外面

四、操作符與表示式

1.算術操作符:+ - * % (只能用於倆個整數)/(可用於整數與浮點數)

2.位移操作符:

左移:末尾補零

右移:邏輯右移:補零,算術右移:補符號位

3.位操作符:&:按位與,|:按位或,^:按位異或(倆個相同的數字異或結果為0,不同為1)

注:他們的操縱數必須時整數

4.單目操作符:sizeof(以位元組為單位,不是關鍵字) &:取地址

5.sizeof使用注意事項:

        int a = 10;
	printf("%d",sizeof(a));
	printf("%d", sizeof a);
	//printf("%d", sizeof int);  
	printf("%d", sizeof(int));

注:sizeof在求變數所佔空間大小時,用變數名可以去掉(),用型別時,不能去掉(),但是我們建議不去掉()

	int a = 1;
	short s = 3;
	printf("%d\n", sizeof(s = a + 5));
	printf("%d\n", sizeof(s));
	printf("%d\n", s);

注:sizeof內部的表示式不參與運算

6.陣列名單獨放在sizeof內部表示整個陣列;&陣列名:表示整個陣列

7.邏輯操作符:

&&:邏輯與,倆邊有一個為假,則表示式結果為假,若左邊為假,後面的即不參與運算

||:邏輯或,倆邊有一個為真即為真,若左邊為真,後面的即不參與運算

例:

        int i = 0, a = 1, b = 2, c = 3, d = 4;
	i = a++&&++b&&d++;
	printf("a=%d,b=%d,c=%d,c=%d", a, b, c, d);

	int i = 0, a = 1, b = 2, c = 3, d = 4;
	i = a++||++b||d++;
	printf("a=%d,b=%d,c=%d,c=%d", a, b, c, d);

8.三目操作符: exp1?exp2:exp3

找倆個數裡大的一個

int a = 10;

int b = 20;

int i = a > b ? a : b;

printf("%d", i);

9.逗號表示式:從左向右求值,整個表示式的結果為最後一個表示式的結果

10.表示式的求值結果有三個影響因素:

1)操作符的優先順序

2)操作符的結核性

3)是否控制求值順序

五、函式

1.傳參:

值傳遞:形參是實參的一份臨時拷貝,形參和實參分別佔有不同的記憶體塊,對形參的修改不會影響實參

傳址:形參和實參依然佔有並不太的儲存空間,但是倆者直接有一層聯絡,形參裡存放的是實參的地址,這樣就可以通過對形參的間接訪問操作實參。

2.連結屬性:在程式連結時起作用

1)外部連結屬性:全域性識別符號具有外部連結屬性,外部連結屬性意味著,一個識別符號,不僅可以在當前原始檔使用,使用exetrn的宣告也可以在其他原始檔使用

2)內部連結屬性:只能在當前原始檔內使用,具有外部連結屬性的識別符號加上一個static關鍵詞修飾就會變成內部連結屬性

static:修飾變數:全域性——改變連結屬性(外部連結屬性->內部連結屬性)

區域性——改變儲存位置——從而改變生命週期

修飾函式:連結屬性(外->內)

3)無屬性(區域性變數,出了作用域即失效,所以無連結屬性)

六、陣列

1.陣列是一組相同型別元素的集合,陣列建立時[]內必須是一個常量,不是使用變數

2.陣列建立時,如果不想指定陣列的大小,就得初始化,陣列的元素個數根據初始化的內容定下來

3.陣列名代表陣列首元素的地址

        char arr1[] = "abcdef";
	char arr2[] = "abcdef";
	if (arr1 == arr2)
		printf("hehe\n");

//陣列名代表首元素的地址,倆個陣列中“abcdef”的地址不同,所以不輸出

        char *p1 = "abcdef";
	char *p2 = "abcdef";
	if (p1 == p2)
		printf("hehe\n");

 

//輸出hehe,p1和p2指向同一塊地址

4.陣列的使用:

int *p = arr;

&arr[i] <==> p+i <==> p[i]

arr[i] <==> *(p+i) <==>*(arr+i)

5.指標:可以理解為一個變數,時一個專門用來存放地址的變數

在32位平臺下時4位元組,64位平臺下8位元組

相關文章