一、學(xué)習(xí)目的
指針是C語言中的一種概念湿刽,正確而靈活地運(yùn)用指針可以使程序簡潔的烁,緊湊。 指針能夠解決跨區(qū)域(不同作用域诈闺,不同的代碼塊)之間的數(shù)據(jù)交互渴庆,為程序編寫提供很大的便利;
C語言提供了一些由系統(tǒng)已定義好的數(shù)據(jù)類型雅镊,也允許用戶建立自己的由不同數(shù)據(jù)組成的組合型的數(shù)據(jù)結(jié)構(gòu)襟雷,稱為結(jié)構(gòu)體,結(jié)構(gòu)體增加了數(shù)據(jù)之間的內(nèi)在聯(lián)系
二仁烹、學(xué)習(xí)內(nèi)容
1耸弄,指針
將地址形象化地稱為“指針”
‘*’:1,表示聲明定義變量的時(shí)候 表示一個(gè)指針變量
int *p;定義一個(gè)指針變量卓缰,這個(gè)指針變量只能存放地址(int類型的地址)计呈,不能存放具體的數(shù);它指向的內(nèi)存空間只能存放整數(shù)
注意:定義指針變量一定要給初值 不確定時(shí)賦值NULL;
float *c = NULL;NULL指向內(nèi)存的起始地址
2征唬,除了定義指針變量外 那就是訪問某個(gè)地址的值
float a = 100.1;
float *c = &a;
printf("%f",*c); 輸出100.1捌显;
‘&’:取某個(gè)變量的地址
void test(int *temp){ //temp實(shí)參
temp++;
}
int test1(int a){
a++;
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
int a = 10;
int *pa = &a;
test(&a); //a的值發(fā)生改變 a實(shí)參
test1(a) //a的值不變,形參
int(*pFunc)(int) = test1; //函數(shù)指針 函數(shù)名就是函數(shù)在內(nèi)存中的首地址
指針變量占八個(gè)字節(jié) 总寒,注意:sizeof(數(shù)組名)會(huì)打印出整個(gè)數(shù)組所占的內(nèi)存空間扶歪,而不是數(shù)組首個(gè)元素的所占的內(nèi)存
printf("%lu\n",sizeof(a)); //輸出 4
printf("%lu\n",sizeof(pa)); //輸出 8
printf("%lu\n",sizeof(a2)); //40 數(shù)組名 打印整個(gè)數(shù)組在內(nèi)存中占據(jù)的字節(jié)
printf("%lu\n",sizeof(pa2)); //8
printf("%lu\n",sizeof(pFunc)); //8 指針變量(不管什么類型)在64位系統(tǒng)占8個(gè)字節(jié)
指針和數(shù)組的關(guān)系:數(shù)組名并不是一個(gè)變量,沒有分配內(nèi)存空間 指針變量有內(nèi)存空間摄闸;區(qū)別:定義一個(gè)數(shù)組 系統(tǒng)會(huì)分配內(nèi)存空間 可以存值
int score[5] = {91,92,93,94,95};
printf("%p\n",score); // 輸出0078F968
printf("%p\n",&score);//輸出0078F968
for(int i=0;i<5;i++){
printf("%d ",score[i]);
}
for(int i=0;i<5;i++){
printf("%d ",*(score+i));
}
printf("%p\n",score);
printf("%p\n",score+1);
printf("%d\n",*(score+1));
printf("%d\n",*score+1); //score[0]+1
printf("%d\n",(*score)++); //91
printf("%d\n",score[0]); //92 前面已經(jīng)+1
printf("%d\n",++(*score)); //93 再次+1然后輸出
指針變量存值的存值的三種方式:
1善镰,指針變量已指向某塊區(qū)域
int a3=10;
int *p = &a3;
*p = 30;//賦值正確
2,,指針指向一個(gè)數(shù)組
int num2[10]={};
int *pNum = num2;
*(pNum+1) = 20;
pNum[1] = 30; //*(pNum+i)相當(dāng)于pNum[i];
第一年枕,第二種都是變量和數(shù)組已經(jīng)分配了內(nèi)存空間炫欺,指針指向變量和數(shù)組,所以能夠操作這些空間熏兄,因此能夠賦值品洛;
3,動(dòng)態(tài)分配內(nèi)存 用malloc() realloc() 方法
注意:自己分配的內(nèi)存空間必須自己釋放 free(); 普通變量的內(nèi)存是系統(tǒng)分配的霍弹,由系統(tǒng)自己釋放
char *pName = malloc(3 * sizeof(char));
//判斷分配是否成功
if(pName == NULL){
//分配失敗
exit(EXIT_FAILURE);
}
pName[0] = 'x';
pName[1] = 'w';
pName[2] = 'j';
printf("%s\n",pName);
當(dāng)之前分配的內(nèi)存不夠是時(shí)毫别,就需要在之前的基礎(chǔ)上重新分配 ;realloc() 必須是之前malloc分配的內(nèi)存才可以用realloc重新再分配 系統(tǒng)自己分配的內(nèi)存空間不能用這個(gè)方法
pName = realloc(pName,4*sizeof(char));
pName[4] = 'o';
printf("%s\n",pName);
free(pName); //釋放內(nèi)存
2典格,結(jié)構(gòu)體
結(jié)構(gòu)體:聲明一種類型 struct Person 類比int float char類型
struct Person{
char name[10];
int age;
char *addr;
};
//定義一個(gè)結(jié)構(gòu)體變量變量
Person per1;
Person per2 = {"zhangsan",19};
per1.name = "lisi"; //出錯(cuò) 數(shù)組一旦定義 地址不能改變
//不能直接給數(shù)組賦值
//若要賦值
per1.name[0] = 'l';
per1.name[1] = 'i';
per1.name[2] = 's';
per1.name[3] = 'i';
// per1.addr = "西南大學(xué)"; //正確 常量字符串的地址是由系統(tǒng)自動(dòng)分配的
per1.addr[0] = 'S';
per1.addr[1] = 'W';
per1.addr[2] = 'U'; //出錯(cuò) 字符指針賦值 必須要有內(nèi)存 賦值前必須分配內(nèi)存空間 per1.addr = malloc(4*sizeof(char));
// typedef 類型重命名
3,鏈表
鏈表是一種常見的重要的數(shù)據(jù)結(jié)構(gòu)岛宦。它是動(dòng)態(tài)地進(jìn)行存儲(chǔ)分配的一種結(jié)構(gòu),鏈表中每一個(gè)元素稱為結(jié)點(diǎn)耍缴,每個(gè)結(jié)點(diǎn)都應(yīng)包括兩個(gè)部分:1砾肺,用戶需要用的實(shí)際數(shù)據(jù)挽霉;2,下一節(jié)點(diǎn)的地址变汪。鏈表中各元素在內(nèi)存中的地址可以不是連續(xù)的
struct Node{ //單鏈表
int date; //數(shù)據(jù)域
Node *Next; //指針域
}侠坎;
struct Node{ //雙鏈表
int date;
Node *next; //后節(jié)點(diǎn)指針
Node *previous//前節(jié)點(diǎn)指
};
初始化頭結(jié)點(diǎn)
//初始化頭結(jié)點(diǎn) 有返回值
Student *initHeader(){
//動(dòng)態(tài)分配內(nèi)存
Student *pTemp = malloc(1*sizeof(Student))
//初始化
pTemp->next = NULL;
return pTemp;
}
//無返回值
void *initHeader(Student **pHeader){
//動(dòng)態(tài)分配內(nèi)存
Student *pTemp = malloc(1*sizeof(Student));
//初始化
pTemp->next = NULL;
//改變外部的值
*pHeader = pTemp;
}
4,文件
打開文件 如果文件不存在 則創(chuàng)建一個(gè)新文件
FILE *fp = fopen("C:/Users/asus/Desktop/abc.txt","w+")
文件的操作:
r 只讀 文件不存在就報(bào)錯(cuò) 從頭開始讀
w 只寫 文件不存在就創(chuàng)建 從頭開始寫 之前存在的內(nèi)容會(huì)被覆蓋
a 只寫 文件不存在就創(chuàng)建 從末尾開始寫
r+,w+,a+ 可讀可寫
struct Student{
//內(nèi)存對(duì)齊
char name[10]; //優(yōu)化為占12個(gè)字節(jié) int的倍數(shù),浪費(fèi)2個(gè) 所以12+4=16
int age;
};
Student xw1 = {"xw",20};
//將結(jié)構(gòu)體寫到文件
fwrite(&xw1,sizeof(Student),1,fp);
三裙盾、學(xué)習(xí)感悟
對(duì)于這次學(xué)習(xí)的內(nèi)容实胸,其他的還行,我感覺最難受的就是指針了指針這個(gè)概念比較復(fù)雜番官,使用也很靈活庐完,因此剛使用常會(huì)出錯(cuò),所以在使用時(shí)要十分小心徘熔,多思考门躯,多比較,多敲代碼酷师,在實(shí)踐中掌握它讶凉。