初始C语言中的指针(翁凯男神MOOC)
運(yùn)算符 &
● scanf("%d",&i);
●獲得變量的地址,它的操作數(shù)必須是變量
● int i; printf("%x",&i);
Int i=;
printf("%p\n",&i);
● 地址的大小是否與int相同取決于編譯器
&不能取的地址
●&不能對(duì)沒(méi)有地址的東西取地址
●&(a+b)
●&(a++)
●&(++a)
int a[];
printf("%p\n",&a);
printf("%p\n",a);
printd("%p\n",&a[]);
指針
●就是保存地址的變量
int i;
int *p=&i;
●指針指向某一個(gè)變量,指針里存放那個(gè)變量的地址
指針變量
●變量的值是內(nèi)存的值
●普通變量的值是實(shí)際的值
●指針變量的值具有實(shí)際值的變量的地址
作為參數(shù)的指針
● void f(int *p);
●在被調(diào)用的時(shí)候得到了某個(gè)變量的地址;
●int i=0;f(&i);
●在函數(shù)里面可以通過(guò)這個(gè)指針訪問(wèn)外面的這個(gè)i
訪問(wèn)那個(gè)地址上的變量*
● *是一個(gè)單目運(yùn)算符,用來(lái)訪問(wèn)指針的值所表示的地址上的變量
● 可以做右值也可以做左值
● int k=*p;
● *p = k+1;
指針應(yīng)用場(chǎng)景
●交換兩個(gè)變量的值
void swap(int *pa.int*pb)
{
int t = *pa;
*pa=*pb;
*pb=t;
}
●函數(shù)返回多個(gè)值,某些值就只能通過(guò)指針?lè)祷?/p>
void minmax(int a[],int len,int *max,int *min); int main(int argc, char **argv)
{
int a[]={,,,,};
int min,max;
minmax(a,sizeof(a)/sizeof(a[]),&min,&max);
printf("min=%d,max=%d\n",min,max); return ;
}
void minmax(int a[],int len, int *max,int *min){
int i;
*min=*max=a[];
for(i=;i<len;i++){
if(a[i]<*min){
*min=a[i];
}
if(a[i]>*max){
*max=a[i];
}
}
}
●函數(shù)返回運(yùn)算的狀態(tài),結(jié)果通過(guò)指針?lè)祷?/p>
●常用的套路是讓函數(shù)返回特殊的不屬于有效范圍內(nèi)的值來(lái)表示出錯(cuò):
● -1 或 0 (在文件操作會(huì)看到大量的例子)
●但是當(dāng)任何數(shù)值都是有效的可能結(jié)果時(shí),就得分開(kāi)返回了
int divide(int a,int b ,int *result); int main(int argc, char **argv)
{
int a=;
int b=;
int c;
if(divide(a,b,&c)){
printf("%d\n%d\n%d\n",a,b,c);
} return ;
}
int divide(int a,int b,int *result)
{
int ret=;
if(b==)ret=;
else{
*result=a/b;
}
return ret;
}
●后續(xù)的語(yǔ)言(C++ Java)采用了異常機(jī)制來(lái)解決這個(gè)問(wèn)題
指針最常見(jiàn)的錯(cuò)誤
●定義了指針變量,還沒(méi)有指向任何變量,就開(kāi)始使用指針
傳入函數(shù)的數(shù)組成了什么?
●函數(shù)參數(shù)表中的數(shù)組實(shí)際上是指針
●size of (a)==size of (int*)
●但是可以用 數(shù)組的運(yùn)算符[]進(jìn)行運(yùn)算
數(shù)組參數(shù)
●以下四種函數(shù)原型是等價(jià)的
● int sum(int *ar,int n);
●int sum (int *,int);
●int sum (int ar[],int n);
●int sum (int [],int);
數(shù)組變量本身就是特殊的指針
●數(shù)組變量本身表達(dá)地址,所以
● int a[10]; int*p=a; //無(wú)需用&取地址
●但是數(shù)組的單元表達(dá)的是變量,需要用&取地址
●a == &a[0]
●[] 運(yùn)算符可以對(duì)數(shù)組做,也可以對(duì)指針做
●p[0] <==> a[0]
● *運(yùn)算符可以對(duì)指針做,也可以對(duì)數(shù)組做
● *a=25;
● 數(shù)組變量是const的指針,所以不能被賦值
● int a[] <==> int *const a =
指針與const
指針是const(指針指向那個(gè)變量,這個(gè)事實(shí)不能被改變)
●表示一旦得到了某個(gè)變量的地址,不能再指向其他變量
int *const q =&i; // q是const
*q = ; // OK
q++; //ERROR
所指的是const
●表示不能通過(guò)這個(gè)指針去修改那個(gè)變量(并不能使得那個(gè)變量成為const)
const int *p = &i;
*p=; // ERROR! (*p)是const
i=; // OK
p=&j; //OK
轉(zhuǎn)換
●總是可以把一個(gè)非const的值轉(zhuǎn)換成const的
void f(const int *x);
int a = ;
f(&a); //OK
const int b=a;
f(&b); //OK
b = a+1; //ERROR
●當(dāng)要傳遞的參數(shù)的類型比地址大的時(shí)候,這是常用的手段:既要用比較少的字節(jié)數(shù)傳遞給參數(shù),又能避免函數(shù)對(duì)外面的變量的修改
const數(shù)組
const int a[]={,,,,};
●數(shù)組變量已經(jīng)是const的指針了,這里的const表明數(shù)組的每個(gè)單元都是const int
●所以必須通過(guò)初始化進(jìn)行賦值
指針運(yùn)算
●給一個(gè)指針加1表示要讓指針指向下一個(gè)變量
int a[];
int *p=a;
*(p+1)--->a[1]
●如果指針不是指向一片連續(xù)分配的空間,如數(shù)組,則這種運(yùn)算沒(méi)有意義
指針計(jì)算
●給指針加,減一個(gè)整數(shù)(+,+=,-,-=)
●遞增遞減(++/--)
●兩個(gè)指針相減(地址的差除以sizeof( 類型))
*p++
●取出p所指的那個(gè)數(shù)據(jù)來(lái),完事之后順便把p移動(dòng)到下一個(gè)位置去
● *的優(yōu)先級(jí)雖然高,但是沒(méi)有++高
●常用于數(shù)組類的連續(xù)空間操作
●在某些CPU上,這可以直接被翻譯成一條匯編指令
char ac[] = {,,,,,,-}; // -1不是有效數(shù)字
char *p=ac
while(*p != -){
printf("%d\n",*p++);
}
遍歷數(shù)組ac
0地址
●當(dāng)然你的內(nèi)存中有0地址,但是0地址通常是個(gè)不能隨便碰的地址
●所以你的指針不應(yīng)該具有0值
●因此可以用0地址來(lái)表示特殊的事情:
●返回的指針是無(wú)效的
●指針沒(méi)有被真正初始化(先初始化為0)
●NULL是一個(gè)預(yù)定定義的符號(hào),表示0地址
●有的編譯器不愿意你用0來(lái)表示0地址
指針的類型
●無(wú)論指向什么類型,所有的指針的大小都是一樣的,因?yàn)槎际堑刂?/p>
●但是指向不同類型的指針是不能直接互相賦值的
●這是為了避免用錯(cuò)指針
指針的類型轉(zhuǎn)換
●void* 表示不知道指向什么東西的指針
●指針類型亦可以轉(zhuǎn)換類型
●int *p = &i; void*q = (void*)p;
●這并沒(méi)有改變p所指的變量的類型,而是讓后人用不同的眼光通過(guò)p看它所指的變量
●我不再當(dāng)你是int啦,我認(rèn)為你就是一個(gè)void!
用指針來(lái)做什么
●需要傳入較大的數(shù)據(jù)時(shí)用作參數(shù)
●傳入數(shù)組后對(duì)數(shù)組做操作
●函數(shù)返回不止一個(gè)結(jié)果
●需要用函數(shù)修改不止一個(gè)變量
●動(dòng)態(tài)申請(qǐng)內(nèi)存時(shí)
malloc
●#include<stdlib.h>
●向malloc申請(qǐng)的空間的大小都是以字節(jié)為單位的
●返回的結(jié)果是void*,需要類型為自己需要的類型
●(int*)malloc(n*sizeof(int))
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int number;
int *a;
printf("輸入數(shù)量");
scanf("%d",&number);
a=(int*)malloc(number*sizeof(int));
for (i=;i<number;i++){
a[i]=i*i;
}
free(a);
return 0;
}
沒(méi)空間了?
●如果申請(qǐng)失敗則返回0,或者叫做NULL
void *p=0;
int cnt=;
while((p=malloc(**))){
cnt++;
free(p)
printf("分配了%d00MB的空間\n",cnt);
free()
●把申請(qǐng)得來(lái)的空間還給系統(tǒng)
●申請(qǐng)過(guò)來(lái)的空間,最終都要還
●混出來(lái)的,遲早都要還的
●只能還申請(qǐng)的空間的首地址
總結(jié)
以上是生活随笔為你收集整理的初始C语言中的指针(翁凯男神MOOC)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 印度什么依据认定拉那克山口为边界点?
- 下一篇: 当兵两年后专升本 升的本科都是什么学校?