C程式設計基礎day08

2021-08-21 11:17:26 字數 4125 閱讀 6389

return 函式在主函式中return結束程式。在其他函式中return結束該函式,但程式仍執行。

exit 在任何函式中執行都會結束程式,也就是結束程序。

如果函式不是寫在main函式前邊,那麼需要在函式被呼叫的前邊某個地方宣告。

乙個函式可以宣告多次,但只能定義一次,宣告的變數名稱和定義的變數名稱可以不一樣。甚至宣告時候可以只寫形參型別,不寫形參名字。

分檔案程式設計: 按功能來分,不同的功能寫在不同的檔案中。***.h、***.c

一次性編譯多個.c檔案辦法, 某個函式在乙個檔案定義,另外乙個檔案中宣告這個函式後,就可以呼叫了。

gcc main.c mystrlen.c -o test或者gcc *.c -o test

多個檔案中不能出現同名函式,static除外。

函式定義內容不寫到.h中原因是:可能乙個.h會被多個.c檔案呼叫,會造成乙個函式在多個.c中被定義了,所以出錯。

函式的宣告一般寫到.h中,.h檔案中可以宣告多個函式,呼叫的主函式可以只寫一句#include"***.h"即可,不用多寫幾句函式宣告。

另外函式宣告寫到.h檔案中,雖然

可能乙個.h會被多個.c檔案呼叫,會造成乙個函式在多個.c中被定義宣告了,但是函式本身就可以多次宣告,但只能一次定義。

同乙個檔案如何避免對同乙個.h檔案同時包含:

1、在標頭檔案地方加上 #pragma once   

2、#ifndef ***_h

#define ***_h

標頭檔案正文

#endif

a.out存在於硬碟(rom)中, 我們執行a.out時候把程式載入到記憶體(ram),執行著的程式叫程序。這裡的記憶體也就是記憶體條。記憶體是溝通cpu和硬碟的橋梁

棧位址分配時候從高到低遞減找到合適的大小分配。

1、記憶體是以1位元組為單位的

2、每個位元組的記憶體都有標號,這個標號就是位址,也就是指標。

3、位址需要儲存, 32位編譯器使用32位(4位元組)儲存此位址

64位編譯器使用64位(8位元組)儲存此位址

4、每個儲存單元(1位元組)分配乙個號碼,就叫編碼。

5、根據位址找到對應記憶體,也叫定址。

char ch;

int a=10;

ch/*ch佔1位元組*/

/*高位址*/

a/*a佔4位元組*/

a/*a佔4位元組*/

a/*a佔4位元組*/

a/*a的首位址=&a*/

/*低位址*/

指標就是位址,位址就是指標。

指標變數時存放位址的變數,習慣上叫做指標。

1、指標也是一種資料型別。 

int * 也是一種型別, int * p; p也是乙個變數,p的型別為int *, 可以對p進行賦值。

p=(int *)123;或者 p = 123;

printf("%p",p);

gcc hello.c -w 忽略列印

2、指標指向誰,就把誰的位址賦給指標。

int a=10;

int * p;

p = &a;

printf("%p",p);和printf("%p",&a);結果一樣

3、直接操作指標變數p沒意義,

4、操作*p代表操作指標所指向的記憶體, *p代表a。

*p=100;

printf("%d",*p);和printf("%d",a);結果一樣

*符號有兩層含義: 

1、在定義變數時,*代表型別,它是指標型別 如 int *p;

2、在使用變數時, *代表操作指標指向的記憶體。如 *p=100;

編譯時候段錯誤一般都是記憶體出錯。

操作野指標變數本身沒有問題,但是操作野指標所指向的記憶體才導致段錯誤。

關於空指標兩個好的習慣:

1、定義指標時候立馬給這個指標賦值為空指標null;

2、給指標指向位址賦值之前最好檢查一下,確認指標不是空指標。

指標大小:

32位編譯器用32位(4位元組)大小儲存位址大小

64位編譯器用64(8位元組)位大小儲存位址大小

vs若想測試64位編譯器可以在debug下拉三角下配置一下編譯管理器,活動平台選擇x64。

多級指標:

如果定義乙個合適型別的變數儲存另乙個變數的位址。在需要儲存變數位址型別的基礎上加乙個*號。

int a=10; 

int *p=&a;

int * *q = &p;// 儲存p的位址,所以在p的型別int *基礎上再加乙個*號變為int **;

int ** *t = &q;// 儲存q的位址,所以在q的型別int **基礎上再加乙個*號變為int **  *;

int *** *m = &t;// 儲存t的位址,所以在t的型別int ***基礎上再加乙個*號變為int *** *;

*m代表t的值,所以*m==t==&q

**m代表*t,*t代表q,即 **m代表q, 所以**m==*t==q=&p;

***m代表**t,**t代表*q, *q代表p, 即***m代表p,所以***m==**t==*q=p=&a;

****m代表***t,***t代表**q, **q代表*p, *p代表a ,即 ****m代表a, 所以****m==***t==**q=*p=a;

總結:多級指標不是看多少星,而是看什麼型別的變數。

1、指標變數也是乙個變數, 是變數就可以進行賦值。

2、指標指向誰,就把誰的位址賦給指標

3、*p操作的是指標指向的記憶體。

不僅僅代表陣列

,*p等價於*(p+0)同時等價於p[0].  實質上記憶體是乙個大陣列,能用指標的地方就能用陣列。

*(p+i)等價於p[i]

int a=10;

int *p = &a;

printf(「%d %d %d」,a, *p, p[0]);

萬能指標: void *

1、不能編譯定義 void型別的變數,因為無法確定型別,編譯器不知道型別就不知道分配多少位元組記憶體。

2、可以定義void *型別變數,因為指標大小是確定的,編譯器是多少位的,指標大小占用記憶體就是多少位的。

3、void *可以指向任何型別的變數。使用指標所指向的記憶體時,最好轉換為它本身的指標型別。

void *p=null;

int a=10;

p=&a;  //err因為這樣話編譯器雖然知道首位址但不知道*p到底操作多大記憶體,若是int *則從首位址開始操作4位元組, 若是char *則從首位址開始操作1位元組。

*  ((int *)p)  =222; //先將p指標變數強制轉化為(int *),然後再對p指向的記憶體進行操作,這次知道是操作4位元組。

printf("*p =%d \n", *( (int*)p)  );

指標步長; int *p; p+1和p值相差為4(int *指標步長為4), 因為*p操作的是int型變數,每次操作需要4個位元組。同理 char *q的指標步長為1.

const 修飾的指標變數。

int a=10;

const int *p =&a; //const修飾的是*(const從左往右數 跳過int 修飾的是*),代表指標所指向的記憶體是唯讀。

*p=200;// err編譯不通過。

p=null;//ok,這條語句可以編譯通過

int const * p2 =&a; //const修飾的還是是*,代表指標所指向的記憶體是唯讀。

*p2=300;// err 同樣編譯不通過,

p2=null;//ok,這條語句可以編譯通過

int  * const p3 =&a; //const修飾的是指標變數p3,代表指標變數的值是唯讀。

*p3=400;// ok, 這條語句可以編譯通過

p3=null;//err編譯不通過。 p3是常量指標,指向的位址不能改,指向哪就是指向哪。

類似於陣列名,陣列名的位址也不能改。

const int  * const p4 =&a; //這個什麼都改不了, 變數不能改, 指標指向的位址不能改。

陣列名是常量,陣列名類似於常指標,其指向首位址,指向的位址不能改。

int a[5]=;

int *p = null;

p =a; 或者p= &a[0];

for(int i=0; i<5; i++)

1、不使用排序找出第二大的數

2、不用庫函式實現字串拷貝功能。

C 學習筆記day08

1 排序函式 void order int p1,int p2 sort ia 9,sizeof int orderint for int i 0 i 9 i coutpers 0 id 1 pers 0 age 29 strcpy pers 0 name liucy pers 1 id 2 per...

java基礎學習day08總結

1.物件導向,面向過程 1 物件導向,面向過程都是一種思想,物件導向是相對面向過程來來說的 面向過程強調的是執行的過程,而物件導向是將功能進行封裝,對功能進行呼叫,強調的是呼叫,比如人開啟門的過程,門開啟則是面向過程,而人開啟門則是物件導向的過程。2 物件導向的三大特點 封裝 繼承 多型 2.類和物...

學習筆記day08

單例設計模式 上圖中,想要實現a,b的配置資訊共享,因為a,b是兩個new,所以必然是不同的物件,一種方法就是將其配置資訊全部設成靜態,但資訊很多時會導致儲存資訊過多。單例設計模式流程 1,主函式main進棧,定義s1 2,等號右邊,single載入進入方法區,接著是single的建構函式。s和ge...