【C语言复习】指针,数组,指针和数组

(本文参考《C和指针》第六章 第八章)

《C和指针》第六章主要讲指针的概念和简单用法,对于初学者要仔细看(燃不清地址和值得),对于有c语言基础比较简单;

第八章加入了数组,数组和指针,二维数组和指针,相比第六章有进阶,本文重点分析书中几个题。

一、第六章指针:概念

1.指针是啥?简单说就是地址

 

2.间接访问操作符:*

什么是间接访问?间接访问又或者说解引用指针就是:通过一个指针访问它所指向的地址的过程。

3.未初始化的指针:野指针

4.空指针:NULL,对NULL指针间接访问将引发错误并终止程序。

5.分析如下表达式:

   int a;

  * & a = 25;

答案:给变量a赋值为25;首先&操作符取a的地址,*从操作符对该地址解引用(间接访问);

和 a = 25;的区别:功能相同,但前者产生的目标代码明显更大更复杂,所以也没人这样写。

6.指针常量:

如下表达式:*100 = 25;(已知100为变量的地址)

该表达式错误!因为*(解引用操作符)只能对指针类型表达式起作用,如果想要完成该功能(将25存在地址为100的内存区域),需要这样写:*(int*)100 = 25;使用强转。

7.指针的指针:

如下表达式:

int a= 1234;
int* b = &a;
int** c = &b;

 8.指针运算:(注意void* 指针)

(1)指针+指针:不合法

(2)指针+-数字:合法,表示单元格的移动

(3)指针-指针:表示两指针中间单元格的数目

(4)int a = 10;  void * p = &a;

思考:p++是否合法??*p = 20;//解引用 给a赋值20   是否合法??

答案是不合法的。,为什么指针可以做减法运算和自减了,就是因为一个前提:知道指针的类型,int*的指针,那么指针减减就是指针见一的单元格,单元格是4个字节,char*的指针减减,就是一个单元格一个字节。

所以void * ,无类型,做指针减法运算就不知道一个单元格是几个字节了,也就无法运算,所以不合法。

同理,不知道指针的数据类型,也就不知道解引用的数据类型,所以就不能解引用。
 

二、第八章:指针和数组

一、一维数组:

1.数组名的几个情况
        1.在定义数组arr的同一个函数中,sizeof(arr)表示整个数组的大小
        2.在定义数组arr的同一个函数中,&arr+1,加整个数组的大小
        3.其它情况,arr表示首元素的地址

书中有这样一句话:“在C中,几乎所有的表达式中,数组名的值是一个指针常量,也就是数组第1个元素的地址。”

但有两个除外:如下:

(1)sizeof()求数组名大小,数组名未退化为指针,所有求得大小是整个数组的大小

int main()
{
	char arr[] = "hello world";
	char* p = arr;
	cout<<strlen(arr)<<endl;//11 strlen求有效长度
	cout<<sizeof(arr)<<endl; //12 sizeof(数组名)求这个结构大小,当然算'\0'了
	cout<<strlen(p)<<endl;  //11等同于strlen(arr)
	cout<<sizeof(p)<<endl;  //4指针都是4

	return 0;
}

(2)&arr+1 :表示取数组整个的大小,再+1表示到数组最后一个元素的后一个地址。

 

 如图可见,第一个arr[0]表示第一个元素,&arr[0] == arr == &arr;

arr+1:指针+1表示+1个单元格,即int*类型的指针加1个单元格,+4字节

但是&arr+1的意义就完全不一样了,&arr已经是作为一个整体了,再+1,就是相当于加这一个整体的单元格,也就是指向第5个单元格,虽然第5个单元格我们并没有使用(其值为0xcccccccc)。

再分析下题:

	int arr[]= {1,2,3,4};	
	int* p1 = (int*)(&arr+1);
	int* p2 = (int*)((int)arr + 1);
	int* p3 = (int*)((int)&arr + 1);
	
	printf("0x%x 0x%x 0x%x\n",p1[-1],*p2,*p3);

 

 2.数组名下标 和 指针+整数

int arr[10];

int* p = arr;

则:arr[2]  == *(arr+2) == *(p+2)

3.字符数组的初始化:

char message[] = { 'a' , 'b','c' , 'd' ,0};

char  message[] ="abcd";   //二者相同

二、二维数组:

1.下标:如图分析

 

2.指针数组与数组指针

(1)指针数组:它是数组,存的东西是指针。int* p[4]; 没啥好说的,比较简单

(2)数组指针:它是指针,指向的是一个数组:int (*p)[10]  :指向整形数组的指针,该数组有10个元素

例如:

int mat[3][10];

int (*p)[10] = mat;// p指向mat的第一行(指向拥有10个int元素的数组的指针),p+整数,则该整数要根据10个int值得长度调整,然后执行+法,也就说p在mat中一行一行的移动

发布了89 篇原创文章 · 获赞 68 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/zDavid_2018/article/details/97015072