C补习----->第七天,指针和二维数组、数组指针、指针数组、const修饰的指针

打印数组元素值的方式:(一维数组)
arr[i]
*(arr+i)
*(arr++) //error
i[arr]
*(p+i)
*(p++)
p[i]


----------------------------------------------------------------------------------------------

1,指针和二维数组:

总结:对于int arr[2][3]的数组来说,arr[0][0]的类型是int ,arr[0]的类型是int *(因为arr[0] == &arr[0][0])
      又因为arr == &arr[0] ,为什么arr不是int **?
      (1)因为arr+1移动了12个字节(一维数组的的大小),如果是int **,应该加一移动4个字节,明显不符合。
      (2)arr[0]是一维数组的数组名,能够代表整个数组,如果将数组名取址赋值个一个指针变量,相当于该指针指向了整个数组,而不是首元素。
      因此:对于arr来说,arr的类型是一个指向一维数组的指针,即数组指针
      
      
      
---------------------------------------------------------------------------------


2,数组指针:指向一维数组的指针:


本质:指针
        格式:
             存储类型 数据类型  (*指针变量名) [元素个数];
             注意:[]的优先级比*要高,所以变量名会首先和[]结合表示的是数组名,而不是指针变量名。
                   所以需要提高*的优先级,故加()。
                   
             分析:
                 存储类型:该数组指针自身的存储位置
                 数据类型: 所指向一维数组的元素类型
                 该指针所指向的类型:数据类型  [元素个数]
                 该指针自己的类型:数据类型 (*)[元素个数]
                 
                 
int arr[5];
//定义一个数组指针指向该一维数组
int (*p)[5] = &arr;

指针的本质:
           用来操作一片连续的空间才有意义。
           
           
int arr[3][4];
//定义一个数组指针
int (*p)[4] = &arr[0];
int (*p)[4] = arr;

                        
3,指针数组:数组元素类型为指针类型


本质:数组

格式: 
    存储类型 数组类型 * 数组名[元素个数]
    
    int a,c,b;
    
    定义一个指针数组用来存储三个变量的地址
    int * p[3] = {&a,&b,&c};
    
    访问:
    int  i;
    for(i=0;i<3;i++)
    {
        printf("%d",*p[i]);
        printf("%d",*(*(p+i)));
    }

----------------------------------------------------------

定义一个指针数组,用来存储二维数组中的每一个小一维?
int arr[3][4];

int *p[3] = {NULL};

for(i=0;i<3;i++)
{
    p[i] = arr[i];
}

*(p[i] + j)
*(*(p+i)+j)

-----------------------------------------------------------
char str[100] = {"wangjia"};//在栈区开辟了100个字节的空间,用来完全存储"wangjia"每一个字符

str[0] = 'j';//OK 
   
char *str = "wangjia";  //在栈区开辟了4个字节的空间,只能存储&'w'
                          注意:此时通过p去操作还是操作的是原空间
*str = 'k'; //error


char *pstr[5] = {"wangjia","haha","xixi","gaga","hehe"};


4,const修饰的指针:


const :被const修饰的变量表示只读

int  a = 90;
conat int a = 89;


总结: 
     (1)对于const来说,修饰完之后的变量的存储位置不会发生改变(依赖于之前的存储位置),只不过被常量化了
     (2)const 没有修饰谁,谁就可以更改,const修饰谁,谁就不能被更改。
     
分为两类:
(1)指向常量的指针:
     int a;
     int *p = &a:
     int const *p = &a;
     const int *p = &a;//代表*p不能被更改但是p的指向以及通过a去修改a的值都是可行的
(2)指针常量:
     int * const p = &a; //代表指针的指向不能被更改,但是可以通过给*p 以及给a去赋值引起a值的改变
     
     
(3)双重修饰:const int * const p  =  &a;//代表*p和p的指向均不可发生改变。
               int const * const p  =  &a;
     
         
-------------------------------------------------------------------------------------------------------------------

1,拆分一个带有空格的字符串,将拆分之后的字符串保存在字符指针数组中
eg:
   char str[100] = {"hello world wangjia"};
   升级版:char str[00] = {"  wang   jia  jia hh"};

#include <stdio.h>

#define N 100
int main(int argc, const char *argv[])
{
	//定义一个字符串
	char str[N] = {'\0'};
	//定义一个指针指向该数组的首元素
	char *p = str;
	printf("请输入一个需要分割的字符串:\n");
	gets(p);

	//定义一个字符指针数组用来存储分割之后的字符串的地址
	char *pStr[10] = {NULL};

	int count = 0;
	//遍历p所指向的数组
	while(*p)
	{
		//判断该位是否为空格
		while(' ' == *p)
		{
			p++;
		}

		//将该位保存在指针数组的第一个元素中
		if('\0' != *p)
		{
			pStr[count++] = p;
		}
		else
		{
			break;
		}
		p++;
		//判断该位不是空格,如果不是,则往后移动
		while(' ' != *p)
		{
			p++;
		}
		//当遇到第一个空格时,将空格用'\0'代替
		*p = '\0';
		p++;
	}

	printf("拆分之后的字符串为以下:\n");
	int j;
	for(j=0;j<count;j++)
	{
		puts(pStr[j]);
	}
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值