程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> C語言07指針高級

C語言07指針高級

編輯:關於C語言

C語言07指針高級


01內存四區

接口封裝和設計思想引導

接口封裝設計思想引導

Sckclient客戶端api模型設計

第一套api函數

#ifndef _SCK_CLINT_H_

#define _SCK_CLINT_H_

 

//函數聲明

// 1、客戶端環境初始化

int sckClient_init(void **handle); //5 day

//

// 2、客戶端發送報文

int sckClient_send(void *handle, unsigned char *data, int datalen);

// 3、客戶端端接受報文

int sckClient_rev(void *handle, unsigned char *out, int *outlen); //1

// 4、客戶端環境釋放

int sckClient_destroy(void *handle);

 

#endif

 

//條件編譯 避免頭文件多次包含

 

#ifndef _SCK_CLINT02_H_

#define _SCK_CLINT02_H_

 

#ifdef __cplusplus

extern "C" {

#endif

 

//函數聲明

// 1、客戶端環境初始化

int sckClient_init2(void **handle); //5 day

//

// 2、客戶端發送報文

int sckClient_send2(void *handle, unsigned char *data, int datalen);

// 3、客戶端端接受報文

int sckClient_rev2(void *handle, unsigned char **out, int *outlen); //1

int sckClient_rev2_Free(void **p); //1

// 4、客戶端環境釋放

int sckClient_destroy2(void **handle);

 

#ifdef __cplusplus

}

#endif

 

 

#endif

我們找到了一套標准,我們可以高效、有目的的學習。

Socket動態庫業務模型思路分析

 

 

經驗話語

Shift+del 刪除一行 ctrl+shift+u大小 ctrl +u 小寫

Alt+F9

F5在多個斷點間切換

 

 

 

排序熱身及數組做函數參數

 

//當數組當做函數參數的話的時候會退化為指針

int printfArray(int a[])

{

int i = 0;

printf("排序之前\n ");

for (i=0; i<10; i++)

{

printf("%d ", a[i]);

}

return 0;

}

 

//int a[10] -=-->int a[] ---->int *a

//數組做函數形參的時候,如果在形參中定義int a[10]語句,

//c/c++編譯器 會做優化,技術推演如下

//int a[10] -=-->int a[] ---->int *a

//總結:函數調用的時候,把數組首地址和有效數據長度傳給被調用函數才是最正確的做法

 

int printfArray04(int *a, int num)

{

 

int i = 0;

printf("排序之前\n ");

for (i=0; i

{

printf("%d ", a[i]);

}

return 0;

 

}

 

 

數據類型本質

數據類型可理解為創建變量的模具(模子);是固定大小內存的別名。

sizeof是操作符,不是函數;sizeof測量的實體大小為編譯期間就已確定

數據類型可以取別名、測量大小

數據類型的封裝

Void數據類型的封裝

數據類型的引申

C一維數組、二維數組有數據類型嗎 3

C語言中,函數是可以看做一種數據類型嗎?15

 

數組類型三大技術難點,壓死初學者的三座大山

 

 

 

變量本質

變量本質:(一段連續)內存空間的別名、內存空間的標號

修改變量的3種方法

1、直接

2、間接。內存有地址編號,拿到地址編號也可以修改內存;於是。。。橫空出世了!

3、c++ 引用

總結:1對內存 可讀可寫; 2通過變量往內存讀寫數據,3不是向變量讀寫數據。4向變量代表的數據空間讀寫數據。變量跑到什麼地方去了?

 

 

內存四區

1、 內存四區模型和函數調用模型

 

基本概念

函數1調用函數2,函數1稱為主調函數 函數2稱為被調用函數

規則1:Main(主調函數)分配的內存(在堆區,棧區、全局區)都可以在被調用函數裡使用吧。

規則2:在被調用函數裡面分配的內存

 

 

1、如果在被調用函數裡面的臨時區(棧)分配內存,主調用函數是不能使用的。

全局區://c++編譯器優化

char *getStr1()

{

char *p = "abcd1";

return p;

}

 

char *getStr2()

{

char *p = "abcd1";

return p;

}

//

臨時區stack

char * getStr3()

{

char buf[100];

memset(buf, 0, sizeof(buf));

strcpy(buf, "abcd1");

return buf;

}

//棧屬性

//棧向下生長的,

//棧的生長方向和內存空間buf存放方向是兩個不同的概念

//堆向上生長的,

//演示:stack生長方向

int main31()

{

float *p1 = NULL;

int *p2 = NULL;

int a = 0;

int b= 0;

char buf[16];

printf("&p1:%x, &p2:%x, &a:%x, &b:%x \n", &p1, &p2, &a, &b);

printf("&buf[0]:%x, &buf[1]:%x", &buf[0], &buf[1]);

 

getchar();

}

 

//軟件開發中 注意野指針

//仔細觀察malloc內存地址大小

//演示heap生長方向

int main32()

{

int a = 0;

int b = 0;

char *p1 = NULL;

char *p2= NULL;

p1 = (char *)malloc(16);

p2 = (char *)malloc(16);

 

printf("\n p1:%x, p2:%x", p1, p2);

printf("\n &p1:%x, &p2:%x", &p1, &p2);

 

//通過內存地址間接賦值

*((char *)0x394da0) = 'a';

*((char *)0x394da1) = 'b';

 

//通過內存地址間接修改內存空間的值

//通過變量名訪問內存空間

//通過內存地址間接訪問內存空間 這就是C語言的靈活性,也是c語言的精華

printf("\np2[0]:%c", p2[0]);

printf("\np2[1]:%c", p2[1]);

 

if (p1 != NULL)

{

free(p1);

}

if (p2 != NULL)

{

free(p2);

}

getchar();

return 0;

}

 

 

 

1:指針是一種數據類型

1)指針也是一種變量,占有內存空間,用來保存內存地址

測試指針變量占有內存空間大小

2)*p操作內存

在指針聲明時,*號表示所聲明的變量為指針

在指針使用時,*號表示 操作 指針所指向的內存空間中的值

*p相當於通過地址(p變量的值)找到一塊內存;然後操作內存

*p放在等號的左邊賦值(給內存賦值)

*p放在等號的右邊取值(從內存獲取值)

3)指針變量和它指向的內存塊是兩個不同的概念

//含義1 給p賦值p=0x1111; 只會改變指針變量值,不會改變所指的內容;p = p +1; //p++

//含義2 給*p賦值*p='a'; 不會改變指針變量的值,只會改變所指的內存塊的值

//含義3 =左邊*p 表示 給內存賦值, =右邊*p 表示取值 含義不同切結!

//含義4 =左邊char *p

//含義5保證所指的內存塊能修改

4)指針是一種數據類型,是指它指向的內存空間的數據類型

含義1:指針步長(p++),根據所致內存空間的數據類型來確定

p++=è(unsigned char )p+sizeof(a);

結論:指針的步長,根據所指內存空間類型來定。

 

02經驗話語

01多級指針做函數參數的理解

 

//在函數調用哪個的時候 實參的值機械的傳給形參(c int數組場景)

//關於形參:

寫在函數上形參變量,還是寫在函數裡面的變量,

從CC++編譯的角度來講,是沒有任何區別的(分配4字節內存);

只不過是 寫在函數上形參變量 ,具有對外的屬性而已

//數據類型分為兩種,一個是簡單的數據類型,一個是復雜的數據類型。碰見復雜的數據類型不能用簡單的數據類型的思維去思考它。拋磚

 

/*

int getbuf01(char *p); int getbuf01(char* p);

int getbuf02(char **p); int getbuf02(char * *p); getbuf02(char ** p);

int getbuf03(char (*p)[]); int getbuf03(char (*p) []); int getbuf03(char ( *p)[ ]);

int getbuf03(char p[10][30]);

int getbuf04(char *****p);

*/

 

//角度1站在c++編譯器的角度 指針就是一個變量,除此之外啥也不是!

//不管是1個* 還是8個*對c++編譯器來講,只會分配4個字節內存

//角度2:當我們程序員要使用指針所指向的內存空間的時候,我們關心,這個內存塊是一維的,還是二維的。

//一般情況:1級指針代表1維,二級指針代表二維。。。

//如果有超過char ***級及3級以上的指針,則不代表幾維的內存。。。

 

//多維數組做函數參數,一般情況下,只能表達到二維,

//如果是三維內存(我們程序員起的名字),已經沒有意義。

//證明一下多維數組的線性存儲

//線性打印

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved