C語(yǔ)言中的指針初階詳解
一、指針的解釋
通俗來講就是某一數(shù)據(jù)的位置。因?yàn)閿?shù)據(jù)的存儲(chǔ)是需要空間的,這個(gè)空間會(huì)有一個(gè)地址,指針就是用來存放這個(gè)地址的,以便于后續(xù)快速的訪問
二、指針變量和地址
1、取地址操作符
在C語(yǔ)言中創(chuàng)建變量就是向內(nèi)存申請(qǐng)空間
#include <stdio.h>
int main()
{
int a = 10;
return 0;
}
我們?cè)趦?nèi)存里可以看到在創(chuàng)建變量a的時(shí)候申請(qǐng)了一塊空間
我們?nèi)〉刂穉之后將地址四行顯示,發(fā)現(xiàn)a存儲(chǔ)在了這個(gè)地址里,0a就是十六進(jìn)制下的10
這里我們介紹一下我們的老朋友,&操作符。在以前的學(xué)習(xí)中,我們?cè)趯W(xué)習(xí)scanf函數(shù)的時(shí)候接觸過這個(gè)操作符,這個(gè)操作符就叫做取地址操作符。

&a取出的是a所占的四個(gè)字節(jié)中地址最小的字節(jié)的地址,通過計(jì)算機(jī)的一套算法,它懂得這個(gè)數(shù)據(jù)是整形,會(huì)取出剩下的三個(gè)地址
(這時(shí)候我們對(duì)scanf函數(shù)的理解也會(huì)深一個(gè)層次
scanf("%d",&a);這里的&a就是取出a的地址,將里邊的值進(jìn)行修改)
2、指針變量和解引用操作
1、指針變量
那我們通過取地址操作符(&)拿到的地址是?個(gè)數(shù)值,這個(gè)數(shù)值有時(shí)候需要存儲(chǔ)起來,?便后期再使?,我們會(huì)把這樣的地址值存放在指針變量中。
#include <stido.h>
int main()
{
int a = 10;
int *pa = &a;//這樣就把取出的a的地址存放到指針pa中了
return 0;
}指針變量也是變量,專門用來存放地址,存放在其中的值都會(huì)被認(rèn)為是地址
2、拆解指針類型
int a = 10;
int *pa = &a;*說明pa是指針變量,int 說明pa這個(gè)指針變量指向的是一個(gè)int類型也就是整型類型的對(duì)象
當(dāng)然如果是short類型的對(duì)象那么就
short i = 10; short *pi = &i;
char類型那么就
char j = 10; char * pj = &j;
3、解引用操作符
#include <stido.h>
int main()
{
int a = 10;
int *pa = &a;
*pa = 20;
return 0;
}這樣就把a(bǔ)的值更改為20了
4、注意事項(xiàng)
int*pa int *pa int* pa int * pa
這幾個(gè)是一樣的,表達(dá)上沒有任何的區(qū)別
3、指針變量的大小
#include <stdio.h>
int main()
{
printf("%zd\n", sizeof(char *));
printf("%zd\n", sizeof(short *));
printf("%zd\n", sizeof(int *));
printf("%zd\n", sizeof(double *));
return 0;
}指針變量的大小取決于地址的大小,指針變量的大小和類型是無關(guān),只要指針類型的變量在相同的平臺(tái)下,大小都是相同的
4、指針的解引用
#include <stdio.h>
int main()
{
int n = 0x12345678;
int *pi = &n;
*pi = 0;
printf("%d",n):
return 0;
}#include <stdio.h>
int main()
{
int n = 0x12345678;
char *pi =(char*) &n; //強(qiáng)制轉(zhuǎn)化,不然是不可以用char類型的指針來接受int類型的變量的
*pi = 0;
printf("%d",n);
return 0;
}- 第一個(gè)運(yùn)行結(jié)果

- 第二個(gè)的運(yùn)行結(jié)果


這說明char類型和int類型的訪問權(quán)限不同,char類型可以訪問一個(gè)字節(jié),也就是十六進(jìn)制下的兩位數(shù),int類型可以訪問四個(gè)字節(jié),也就是十六進(jìn)制下的八位數(shù)
5、void*指針
無具體類型的指針,也叫泛型指針,可以接受任何類型的地址但它不能夠進(jìn)行解引用操作,以及指針±整數(shù)的運(yùn)算(下面來說)
三、指針的運(yùn)算
1、指針±整數(shù)
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int* p = &arr[0];
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
for (i = 0; i < sz; i++)
{
printf("%d ", *(p + i));//p+i 這?就是指針+整數(shù)
}
return 0;
}這里的指針經(jīng)過加減后是通過單位進(jìn)行訪問的,也就是如果是int類型,那么指針就加了四個(gè)字節(jié),char加一個(gè)字節(jié),short加兩個(gè)字節(jié)。
2、指針 - 指針
#include <stdio.h>
int my_strlen(char* s)
{
char* p = s;
while (*p != '\0')// \0 之前的元素為字符串中的元素
p++;
return p - s;
}
int main()
{
printf("%d\n", my_strlen("abc"));
return 0;
}這樣就可以算出字符串中的元素個(gè)數(shù)
3、指針的關(guān)系運(yùn)算
#include <stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
int* p = &arr[0];
int i = 0;
int sz = sizeof(arr) / sizeof(arr[0]);
while (p < arr + sz) //指針的???較
{
printf("%d ", *p);
p++;
}
return 0;
}四、野指針
1、野指針形成的原因
#include <stdio.h>
int main()
{
int* p;//局部變量指針未初始化,默認(rèn)為隨機(jī)值
*p = 20;
return 0;
}2、指針越界訪問
#include <stdio.h>
int main()
{
int arr[10] = { 0 };
int* p = &arr[0];
int i = 0;
for (i = 0; i <= 11; i++)
{
//當(dāng)指針指向的范圍超出數(shù)組arr的范圍時(shí),p就是野指針
*(p++) = i;
}
return 0;
}3、指針指向的空間釋放
#include <stdio.h>
int* test()
{
int n = 100;
return &n;
}
int main()
{
int* p = test();
printf("%d\n", *p);
return 0;
}這些原因其實(shí)都很常見,也很有規(guī)矩,看一下就能看出來是理所應(yīng)當(dāng)?shù)模瑳]啥需要解釋的
想辦法規(guī)避它們就行了
五、const 修飾指針
1、const修飾變量
#include <stdio.h>
int main()
{
int m = 0;
m = 20;//m是可以修改的
const int n = 0;
n = 20;//n是不能被修改的
return 0;
}被const修飾的變量是不能修改的
2、const修飾指針變量
int * p;//沒有const修飾 const int * p;//const 放在*的左邊做修飾 int const * p;//const 放在*的左邊做修飾 int * const p;//const 放在*的右邊做修飾
第二行和第三行實(shí)際是一樣的。
我的理解是看const修飾的量,被其修飾的量是不能改變的,我們先來看第二行和第三行代碼,*p不能改變,*p是變量值,也就是指針指向的那個(gè)變量的內(nèi)容,它是不能夠改變的,但p也就是地址,指針本身,是可以改變的。
第四行代碼,const修飾p,地址,指針本身,是不能改變的,但指針指向的變量的內(nèi)容是不能改變的
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
詳解C++中的ANSI與Unicode和UTF8三種字符編碼基本原理與相互轉(zhuǎn)換
在C++編程中,我們有時(shí)需要去處理字符串編碼的相關(guān)問題,常見的字符編碼有ANSI窄字節(jié)編碼、Unicode寬字節(jié)編碼及UTF8可變長(zhǎng)編碼。很多人在處理字符串編碼問題時(shí)都會(huì)有疑惑,即便是有多年工作經(jīng)驗(yàn)的朋友也可能搞不清楚。所以有必要講一下這三種字符編碼以及如何去使用它們2021-11-11
C++中的Lambda表達(dá)式及表達(dá)式語(yǔ)句
這篇文章主要介紹了C++中的Lambda表達(dá)式及表達(dá)式語(yǔ)句,表達(dá)式這個(gè)概念在C++中屬于比較細(xì)節(jié)的知識(shí)了,很多時(shí)候我們只用知道怎么用,對(duì)于編譯器內(nèi)部怎么處理我們并不關(guān)心;并且關(guān)于左值和右值這個(gè)概念,也是C++比較深的一個(gè)小知識(shí)點(diǎn),需要的朋友可以參考一下2021-12-12

