0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

C語言指針

嵌入式技術 ? 來源:嵌入式技術 ? 作者:嵌入式技術 ? 2022-08-18 17:36 ? 次閱讀

C語言指針

1、指針定義

??指針是一個變量, 它保存的是另一個變量的地址, 即內存位置的直接地址。

int ptr; //整型變量,ptr+1 表示變量值+1;
const int ptr;//只讀變量,和int const ptr效果一致;
int *ptr1; //定義一個整型指針, ptr+1 表示地址偏移 int 類型字節(jié);
int ptr[3];//3 個成員的整型數(shù)組, ptr+1 表示指向 ptr[1]的地址;
int *ptr[3];//指針數(shù)組,ptr[3]是數(shù)組,int*再與 ptr[3]結合成指針數(shù)組, 表明數(shù)組中保存著 int 類型的指針, ptr+1 表示指向 ptr[1][]的地址, 即二維數(shù)組 ptr[1][0]的地址;
int (*ptr)[3];//數(shù)組指針,()優(yōu)先級高,(*ptr)是指針, 再與[3]結合, 說明指針所指向的內容是數(shù)組, 最后和 int 結合, 表示數(shù)組元素類型是 int 類型。ptr+1 表示指向 ptr[1][]的地址, 即 ptr[1][]的地址;
int **ptr;//二維指針變量, 保存一維指針變量的地址;
int const *ptr;//常量指針,ptr指向的內容不可以修改,但可以改變指向;
int *const ptr;//指針常量,ptr的指向不可以修改,但可以修改指向的內容;

2、*p++、 *(p++)、 *++p、 ++*p、 *p+1、 *(p+1)

#include 
int main()
{
	int buff[]={10,20,30};
	int *p=buff;
	/*1 buff[0]的地址:&buff[0]*/
	printf("print1 buff addr:%#x\n",buff);
	/*2 buff[0]的地址:&buff[0]*/
	printf("print2 p addr:%#x\n",p);
	/*3 偏移 sizeof(int)字節(jié)*/
	printf("print3 p+1 addr:%#x\n",p+1);
	/*4 取 buff[0]的值*/
	printf("print4 *p=%d\n",*p);
	/*5 取 buff[0]的值+1*/
	printf("print5 *p+1=%d\n",*p+1);
	/*6 地址偏移 sizeof(int)再取值, 即 buff[1]*/
	printf("print6 *(p+1)=%d\n",*(p+1));
	/*7 先取*p 的值,再 p+1*/
	printf("print7 *p++=%d\n",*p++);
	/*8 先取*p 的值, 再(*p)+1*/
	printf("print8 ++*p=%d\n",++*p);
	/*9 先 p+1,再取*(p+1)*/
	printf("print9 *++p=%d\n",*++p);
}
  • 運行結果:
[xsw@xsw cc]$ ./a.out
print1 buff addr:0xbf98f2a0
print2 p addr:0xbf98f2a0
print3 p+1 addr:0xbf98f2a4
print4 *p=10
print5 *p+1=11
print6 *(p+1)=20
print7 *p++=10
print8 ++*p=21
print9 *++p=30

3.NULL指針和void*指針

??NULL 是標準宏定義, 用來表示空指針常量, 在聲明指針變量時若沒有確切地址賦值, 可以給指針變量賦NULL。

#include 
int main()
{
	char *ptr=NULL;
	printf("ptr addr:%d\n",ptr);
	return 0;
}
  • 執(zhí)行結果
[xsw@xsw cc]$ ./a.out
ptr addr:0

?在大多數(shù)操作系統(tǒng)中程序不允許訪問地址為 0 的內存, 因為該內存是操作系統(tǒng)保留的。 指針指向地址為 0 的內存表示該指針指向的地址不可訪問。 按照慣例 NULL 指針假定為不指向任何東西。

??void 表示”無類型”, void*指針表示”無類型指針”, 即可指向任何數(shù)據類型。


#include 
int main()
{
	void *p;
	int a=100;
	char buff[]={0,10,20,30};
	p=&a;//保存 int 型變量地址
	//void*指針訪取值時要保證和所指向的變量類型一致
	printf("*p=%d\n",*((int *)p));//強制轉換成 int*
	p=buff;//指向字符數(shù)組首地址
	//強制轉換成 char*
	printf("*p=%d\n",*(char *)p);//buff[0]
	printf("*(p+1)=%d\n",*(char *)(p+1));//地址往后偏移 char 字節(jié): buff[1]
	printf("*p+1=%d\n",*(char *)p+1);//取出的值+1: buff[0]+1
	return 0;
}
  • 執(zhí)行結果
*p=100
*p=0
*(p+1)=10
*p+1=1

??注:void 幾乎只能用于指針的聲明和函數(shù)返回值以及函數(shù)形參, 不能用于變量的定義。

4、二維指針

??二維指針:指向指針的指針。 保存一維指針的地址。
??指針聲明:int **ptr;

#include 
int main()
{
	int a=0x12;
	int *ptr=&a;//一維指針保存變量地址
	int **pptr=&ptr;//二維指針保存一維指針本身地址
	//1 ptr==&a
	printf("line1:a addr:%#x\n",ptr);
	//2 *(&ptr)==&a
	printf("line2:*(&ptr)=%#x\n",*(&ptr));
	//3 pptr==&ptr
	printf("line3:pptr :%#x\n",pptr);
	//4 *ptr==*(&a)==a
	printf("line4:*ptr=%#x\n",*ptr);
	//5 *(&ptr)==ptr==&a
	printf("line5:*pptr=%#x\n",*pptr);
	//6 **pptr==**(&ptr)==*ptr=*(&a)
	printf("line6:**pptr=%#x\n",**pptr);
	//7 ***(&pptr)==**(&ptr)==*ptr==*(&num)=0x12
	printf("line7:**pptr=%#x\n",***(&pptr));
}
  • 執(zhí)行結果:
[xsw@xsw cc]$ ./a.out
line1:a addr:0xbf90384c
line2:*(&ptr)=0xbf90384c
line3:pptr :0xbf903848
line4:*ptr=0x12
line5:*pptr=0xbf90384c
line6:**pptr=0x12
line7:**pptr=0x12

5、數(shù)組指針

指針定義:int (p)[n];指向數(shù)組整體的指針。 數(shù)組指針類型:int ()[n];

()優(yōu)先級高, 所以 p 是一個指針, 指向一個整型的一維數(shù)組, 一維數(shù)組的成員個數(shù)位 n, 也就是說 p 的步長為 n。 即 p+1 偏移的地址為 n 個 int 型長度。 因此數(shù)組指針也稱為行指針。

優(yōu)先級: () > [] > *

示例一:數(shù)組指針指向一維數(shù)組示例

#include 
int main()
{
	int buff[]={11,22,33,44,55,66};
	int (*ptr)[6];//數(shù)組指針,指向數(shù)組整體
	ptr=&buff;
	int i;
	//數(shù)組指針 ptr+1 偏移指向的數(shù)組整體大小,即偏移 6*sizeof(int)=24 字節(jié)
	printf("ptr addr:%#x\n",ptr);
	printf("(ptr+1) addr:%#x\n",ptr+1);
	/*數(shù)組指針遍歷 buff*/
	for(i=0;i<6;i++)
	{
		printf("%d ",*(*ptr+i));//或*(ptr[0]+i)或 ptr[0][i]
	}
	printf("\n");
	return 0;
}
  • 執(zhí)行結果:
[root@xsw cc]# ./a.out
ptr addr:0xbfbc8ce0
(ptr+1) addr:0xbfbc8cf8
11 22 33 44 55 66

示例二:數(shù)組指針指向二維數(shù)組示例:

#include 
int main()
{
	int buff[][3]={1,10,3,4,5,6};//每行有 3 個元素
	int (*p)[3]=buff;
	printf("*p[0]=%d\n",*p[0]);//等價于 buff[0][0]
	printf("*(p[0]+1)=%d\n",*(p[0]+1));//等價于 buff[0][1]
	printf("*p[1]=%d\n",*p[1]);//等價于 buff[1][0]
}

6、指針數(shù)組

??定義:int p[n];數(shù)組中保存 int指針。指針數(shù)組類型:int *[n], p的類型是 int **,p+1 偏移的地址為:sizeof(int *)。
??示例一:將一維數(shù)組賦值給指針數(shù)組:

#include 
int main()
{
	int buff[]={11,22,33,44,55,66};
	/*
	//初始化直接賦值
	int *ptr[10]={&buff[0],&buff[1],&buff[2],&buff[3],&buff[4],&buff[4]}
	*/
	int *ptr[10];//指針數(shù)組,數(shù)組中保存 int 型指針
	/*數(shù)組指針賦值*/
	int i;
	for(i=0;i<6;i++)
	{
		*(ptr+i)=&buff[i];//或:buff+i
	}
	for(i=0;i<6;i++)
	{
		printf("%d ",*(*ptr+i));
	}
	printf("\n");
	return 0;
}
  • 運行結果:
[root@xsw cc]# ./a.out
11 22 33 44 55 66

??示例二:將二維數(shù)組賦值給指針數(shù)組示例

#include 
void tow_array(int (*buff)[3],int line);
int main()
{
	int buff[][3]={1,10,3,4,5,6};//每行有 3 個元素
	int *p[3];
	*p=buff[0];
	p[0]=buff[0];
	*(p+1)=buff[1];
	printf("%d\n",(*p)[0]);//等價于:p[0][0]
	printf("%d\n",(*p)[1]);//等價于 p[0][1]
	printf("%d\n",*(p[0]+1));//等價于 p[0][1]printf("%d\n",*(p+1)[0]);//等價于 p[1][0], *(p+1)指向 buff[1][0]地址
	printf("%d\n",*(*(p+1)+1));//等價于 p[1][1]
}
printf("%d\n",*(p+1)[0]);//等價于 p[1][0], *(p+1)指向 buff[1][0]地址
printf("%d\n",*(*(p+1)+1));//等價于 p[1][1]

??注:二維數(shù)組賦值給指針數(shù)組時 p=buff 是錯誤的。

7、函數(shù)指針

??函數(shù)指針:指向函數(shù)的指針變量。 本質是指針變量。

#include 
int func(int a,int b);
int main()
{
	//pfunc 表示函數(shù)指針變量
	int (*pfunc)(int ,int );//定義函數(shù)指針,可以在定義時初始化
	pfunc=func;//初始化函數(shù)指針,也可寫成 pfunc=&func
	int data=pfunc(10,20);
	printf("%d\n",data);
}
int func(int a,int b)
{
	return a+b;
}

8、回調函數(shù)

#include 
int func_1(int a,int b);
int func_2(int a,int b);
int func_3(int a,int b);
void func_Callback(int a,int b,int (*pfunc[])(int,int),int num);
int main()
{
	int data;
	int i=0;
	//定義函數(shù)指針數(shù)組
	int (*pfunc[3])(int ,int)={func_1,func_2,func_3};
	func_Callback(30,20,pfunc,sizeof(pfunc)/sizeof(int *));
}
int func_1(int a,int b)
{
	printf("\t[%s] %s line:%d %d+%d=%d\n",__FILE__,
										__FUNCTION__,
										__LINE__,
										a,b,a+b
										);
	return a+b;
}
int func_2(int a,int b)
{
	printf("\t[%s] %s line:%d %d*%d=%d\n",__FILE__,
											__FUNCTION__,
											__LINE__,
											a,b,a*b
											);
	return a*b;
}
int func_3(int a,int b)
{
	printf("\t[%s] %s line:%d %d%%%d=%d\n",__FILE__,
											__FUNCTION__,
											__LINE__,
											a,b,a%b
											);
	return a%b;
}
/***************************回調函數(shù)******************
**
**
**形參:int a,int b ---函數(shù)指針所需要動形參
** int (*pfunc[])(int,int) --- 函數(shù)指針數(shù)組
** int num ---函數(shù)指針數(shù)組成員個數(shù)
**
*********************************************************/
void func_Callback(int a,int b,int (*pfunc[])(int,int),int num)
{
	int i;
	int data;
	for(i=0;i
  • 運行結果:

[xsw@xsw cc]$ ./a.out
[func.c] func_1 line:17 30+20=50
data=50
[func.c] func_2 line:22 30*20=600
data=600
[func.c] func_3 line:27 30%20=10
data=10

審核編輯:湯梓紅

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • C語言
    +關注

    關注

    180

    文章

    7594

    瀏覽量

    135864
  • 指針
    +關注

    關注

    1

    文章

    478

    瀏覽量

    70491
收藏 人收藏

    評論

    相關推薦

    不錯的C語言指針教程.pdf

    不錯的C語言指針教程.pdf
    發(fā)表于 08-11 00:28

    C語言指針的高級用法

    C語言指針搞不好說實話實在是太麻煩的一個東西,而且C語言指針還是繞不過的一個坎,所以我覺得還是苦
    發(fā)表于 11-06 16:50

    什么是C語言指針變量

    C語言指針變量
    發(fā)表于 12-15 07:22

    C語言指針在32位單片機上有哪些應用呢

    C語言指針有哪些應用呢?C語言指針在32位單片機上有哪些應用呢?
    發(fā)表于 02-25 07:37

    C語言指針電子教程

    本資料是一份不錯的關于C語言指針的電子教程,希望對大家有所幫助... 指針簡介 指針C
    發(fā)表于 07-30 16:00 ?77次下載

    C語言_指針總結_經典講解

    C語言_指針總結_經典講解。
    發(fā)表于 01-06 13:47 ?10次下載

    C語言指針函數(shù)和函數(shù)指針詳細介紹

    C語言指針函數(shù)和函數(shù)指針詳細介紹。。。。。。。
    發(fā)表于 03-04 15:27 ?5次下載

    徹底搞定C語言指針詳解完整版

    徹底搞定C語言指針詳解完整版。
    發(fā)表于 05-10 17:04 ?0次下載

    C語言指針跨函數(shù)訪問

    C語言指針跨函數(shù)訪問
    發(fā)表于 12-16 17:23 ?1次下載

    嵌入式開發(fā)之C語言指針

    學習 C 語言指針既簡單又有趣。通過指針,可以簡化一些 C 編程任務的執(zhí)行。
    的頭像 發(fā)表于 11-06 17:09 ?3195次閱讀
    嵌入式開發(fā)之<b class='flag-5'>C</b><b class='flag-5'>語言</b>的<b class='flag-5'>指針</b>

    C語言指針的表達式實例程序說明

    本文檔的主要內容詳細介紹的是C語言指針的表達式實例程序說明。
    發(fā)表于 11-05 17:07 ?4次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>指針</b>的表達式實例程序說明

    C語言指針指針變量的簡介和運算實例程序免費下載

    本文檔的主要內容詳細介紹的是C語言指針指針變量的簡介和運算實例程序免費下載
    發(fā)表于 11-05 17:38 ?14次下載

    C語言指針的理解使用

    C語言指針的理解使用指針變量的聲明給普通變量的賦值對比給指針變量的賦值代*的指針的使用說明
    發(fā)表于 01-13 13:42 ?3次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>指針</b>的理解使用

    C語言進階】C語言指針的高階用法

    C語言進階】C語言指針的高階用法
    的頭像 發(fā)表于 08-31 13:24 ?2251次閱讀

    C語言指針學習筆記

    本文從底層內存分析,徹底讓讀者明白C語言指針的本質。
    的頭像 發(fā)表于 11-05 17:40 ?110次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>指針</b>學習筆記