C基础6--指针一

【2】指针
地址:内存会采用统一编址,来管理内存。每一个内存的区域都会有一个编号这个编号就叫做地址。
指针:指针是指向地址的
指针变量:存放地址的变量就是指针变量
以后再用的时候统称为指针

 【1】指针是一个特殊的变量,它里面存储的数值被解释为内存里的一个地址,
	想要透彻的搞懂,就必要从计算机底层进行解释:
	
	---------------------------------------------
				 计算机应用程序
		
		操作系统    编译原理    计算机网络
		
	------------------------------------
				计算机体系架构
				
				计算机组成
		
	中央处理器	   内存    硬盘(数据)   输入输出设备
-------------------------------------------------

操作系统 将硬件和软件结合起来,给程序员提供了一种对物理内存空间的抽象–虚拟存储器

虚拟存储器是一块很大的空间,可以想想成一块很大的小方格。
每个小方格都有唯一的编号,也就是所谓的地址。
如 int a= 2333    开辟了四个字节的内存,a变量的地址 一般为a变量的首地址。
我们可以使用取地址符号  &  来获取a的地址,
因为直接操作内存中的值,会大大的提高程序的操作效率。指针便诞生了。

指针类型并不是单独的存在的,它是由其他的类型派生而来,如指向 int 的指针类型
指向 double 的指针类型,可以使用这样的方法进行定义:
			int *p; 
			double *c;
			char*b;

当你完成定义之后,C程序同样的会在内存中开辟出一块空间,用来存放指针类型的值。
	
		int a =2333 ; 
	
	 -------------
	|			  |
	|指针类型的值 |---- 内存地址
	|			  |
	 -------------

特别的需要去区分三个概念:
		
		指针类型:        int*
		指针类型的变量:  p
		指针类型的值:    内存地址
		
因为通常 把他们全部都称为指针,所以经常会不知所以然。


	int  *p;   int *p = &a; 
		//定义的时候,是这样定义的,但是运算的时候  p=&a;
	称作p是指向 int 类型变量a的指针。简称 p指向a.
	
	通过指针类型可以正确的读出在该地址上存储的数据。
	(因此可以通过指针的类型来  控制  指针的步进)
	指针进行加减运算的时候,运算的是指针类型的大小,比如 int 是四个字节	
		指向下一个完整的数据。
		
		
		那么如何获取这块地址上保存的值呢?
		这是需要用到运算符  * (解引用运算符)  *p =2333
		
	
			 		   
	   #include <stdio.h>
	   int main(int argc, const char *argv[])
	   {
	       int a[10]={123,456,789,147,258,369};
		   printf("&a[0]=%p\n",&a[0]);
	       int *p=NULL;
		   p = &a[0];
		   printf("*p=%d,p=%p,&p=%p\n",*p,p,&p);
		   puts("");			  
		   printf("*(p+1)=%d,   p+1=%p\n",*(p+1),p+1);
		   printf("a[1]=%d, &a[1]=%p\n",a[1],&a[1]);		  
		   return 0;
	  } 

    //可以说敲完了这趟代码,我应该是明白了一点东西
	//就行整形变量的定义 是 int 类型一样,同样的指针类型 是 int* 这个是一个整体,
    // int* p =&a[0];   和 int* p ;  p=&a[0]; 是一个意思,我现在是明白了。他是一个整体。
	//再就是 p 得到的是地址,  *p 是解引用的意思。(*)这是个运算符,一个符号。 就像 int* 是一个整体的一样,明白了。
	
	
	【2】一维数组指针:关键的就是一个步进了。
	
	【3】二维数组  是数组的数组
			使用类型+ [i][j]来定义;其中第一个[]用来描述有几个一维数组,
					               第二个括号用来描述一维数组的大小。
							
1.代码运行的时候是在虚拟内存上的
						虚拟内存
	                   |--------|0xffff ffff
物理内存:	           |	    |3-4G
|-------|     完成映射 |--------|0xc000 0000
|	    |     mmu      |	    |0-3G
|	1G  |--------------|		|
|	    |              |		|
---------	           |---------
	
【3-4G】内核空间,操作系统所单独占用的空间
【0-3G】用户空间,每一个程序运行的时候单独拥有
		0-3g的内存管空间

3G	---------------------------
		堆区 :需要手动申请和释放(malloc/free)
	---------------------------
		栈区 :用户的函数,局部变量,是有操作系统自动申请和释放的
	---------------------------
		.bss :全局的未初始化的变量,以及static修饰的变量
	---------------------------
		.data:存放用户的数据
	---------------------------
		.ro(read only) :存放字符串常量
	---------------------------
		.text :文本段
0G	---------------------------


指针定义形式
<存储类型> <数据类型> *<变量名>;

char  *p;
short *t;
int   *q;    		//*这里的*是一个标识符,代表定义的是指针类型的变量			  
sizeof(char *); 	//4 p+1  移动1字节
sizeof(int *);  	//4 q+1  移动4字节
sizeof(short *);	//4 t+1  移动2字节

【3】和指针相关的符号
* //取出地址中的内容
& //取地址符

	  #include <stdio.h>
	  int main(int argc, const char *argv[])
		  {
			  int a=5,*p;   //int 了一个指针型变量。
			  p=&a;         //p 是取a的地址,  p=&a;
		  
			  printf("&a=%p\n",&a);  //打印a的地址,
			  printf("*p=%d\n",*p);  //*p的含义,取出地址中的内容.
			  printf("p=%p\n",p); 
			
			return 0;			
		  }
				
			&a=0xbfb43328
			*p=5
			p=0xbfb43328

【4】一维数组和指针
int a[3];
a[0] a[1] a[2]

	int *p = a;

	数组访问:
	*(数组的首地址+偏移)
	数组名字和数组下标的方式
	
	a[i] <=====>p[i] <====> *(a+i) <====>*(p+i)

	指针是否可以按照数组的方式来访问?
	答案:可以


注意:
	p++ //可以
	a++ //不行,原因a是数组名,它是常量不能做加减操作。


练习:

	1.将一个int类型的数x=0x12345678的各个字节打
		印出来p[i],并求个字节的和

		  5 #include <stdio.h>
		  6 int main(int argc, const char *argv[])
		  7 {
		  8     int x=0x12345678;     //int 是四个字节 
		  9     char *p =(char*) &x;  //现在*p存放的是x的地址,                           
		 10 
		 11     int i ,sum=0 ;
		 12 
		 13     for(i=0;i<4;i++){
		 14         printf("%#x\n",p[i]);
		 15         sum+=p[i];
		 16     }
		 17 
		 18     printf("you will better ,xu !\n");
		 19     printf("sun=%d\n",sum);
		 20 
		 21     return 0;
		 22 }
		 
	//你现在想一下,int 是四个字节,char是一个字节 8bit,但是能够存放?
	//为什么?指针指向的是什么?




	2.指针的方式(格式)
			
	//strcat是连接字符串的函数。函数返回指针,两个参数都是指针。
	//第一个参数所指向的内存的地址必须能容纳两个字符串连接后的大小。
		strcat(man strcat)
			char *mystrcat(char *dest, const char *src);   //   const是一个C语言的关键字,它限定一个变量不允许被改变。
			功能:完成字符串的拼接
			参数:
				@dest:目标串的首地址
				@src :源串的首地址
			返回值:dest首地址

			#include <stdio.h>
			
			char *mystrcat(char *dest ,const char *src)         //这里是一个指针函数。 
			{
				char *h=dest;        		  //传进来的是dest的地址, src的地址,之后*h 保存了dest的地址的首地址。
				if(dest==null||src==null)     //
				{
					printf("input error \n");
					return null;              //-->(void *)0;
				}
				while(*dest++);
				dest--;    
				while(*src) *dest++=*src++; 
				return h;
			}

			int main(int argc, const char *argv[])
			{

					printf("chenxu you will better!\n");
					char dest[100];
					char src[100];      //宸茬粡鐢宠浜嗗唴瀛?		char *back=null;
					printf("input (src)> ");
					scanf("%s",src);
					printf("input (dest)> ");
					scanf("%s",dest);       //鎶婂瓧绗﹀垎閰嶈繘鍘伙紝
															
					back=mystrcat(dest,src);
					printf("dest=%s\n",dest);
					printf("back=%s\n",back);

				return 0;
			}

strcmp
int strcmp(const char *s1, const char *s2);
功能:完成字符串比较
参数:
@s1:字符串2
@s2:字符串2
返回值:
>0 s1大
=0 相等
<0 s2大

		strcpy
			char *strcpy(char *dest, const char *src);
			功能:完成字符串的拷贝src-->dest
			参数:
				@dest:目标串的首地址
				@src :源串的首地址
			返回值:dest首地址

			
		strlen
			 size_t strlen(const char *s);
			功能:求字符串长度
			参数:
				@s:字符串的首地址
			返回值:返回的长度

		
	3.mystrstr
			str1          str2 
		123123abcdfsdf   abc
		在终端上输入两个字符串,那第二个字符串在字符串一中比较
		如果在字符串1中找到字符串2,将找到的字符串的首地址返回。

		char *strstr(const char *src, const char *sub);
		功能:在src中找sub
		参数:
			@src:源字符串
			@sub:子串
		返回值:成功返回找到字符串的地址,失败NULL


	4.在终端上输入一个字符串,将他转化为整数(myatoi)
		"1231231" ---转化为整数->1231231
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值