C语言---指针——重点,重点,重点!!!!

一、初识指针

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdbool.h>
int main(void)
{
    int * p;   
    /*
     1.p是变量的名字,int*表示p变量存放的是int类型变量的地址,
     2.P是变量名字,p的数据类型是int*类型
     3.所谓int*类型,实际就是存放int变量地址的类型

    */
    int i = 3;
    p = &i; 
    /*
    1. p保存了i的地址,因此P指向i
    2. P不是i,i也不是P,修改p的值不影响i的值,修改i的值也不会影响P
    3. 如果一个指针变量指向某个普通变量,则 *指针变量  就完全等同于  普通变量
    
 例子:
         如果P是个指针变量,并且p存放了普通变量i的地址,则p指向了普通变量i
         *p 就完全等同于 i

         
    */
    //p = i; //错误,因为p只能存放int类型变量的地址
    
    return 0;
}

二 、指针

    1.指针定义

       指针就是地址,而地址是内存单元的编号(从0开始的非负整数,编号范围:4G),每个内存  单元的大小是1个字节

   指针本质就是一个操作受限的非负整数。

   2.指针与指针变量区别

          指针就是地址,地址就是指针,地址就是内存单元的编号

         指针变量-是存放地址的变量    

       注意:通常口头把指针变量简称指针,实际它们含义并不一样

   3.指针的重要性

  •   表示一些复杂的数据结构
  • 快速的传递数据
  • 使函数返回一个以上的值
  • 能直接访问硬件
  • 能够方便的处理字符串
  • 是理解面向对象语言中引用的基础

4.指针的分类

  • 基本类型指针
   * 的含义

     1>定义指针变量

          int *p 定义了一个名字叫p的变量,int *表示p只能存放int类型变量的地址

    2.>指针运算符

       如果p是一个指针变量,则*p 表示 以p的内容为地址的变量

  • 指针和数组

          1>  指针和一维数组的关系

                 一维数组名------是指针常量,它存放的是一维数组第一个元素的地址

      

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>


int main(void)	
{
	int  a[5]; //a是数组名,5是数组元素个数,元素就是变量
	//int a[3][4];
	int b[3];
    a=&a[2]  //错误,因为a是一个指针常量
	printf("%#X\n", &a[0]); //结果 0XA5D6F7B8
	printf("%#X\n", a);     //0XA5D6F7B8
	//   一维数组名------是指针常量,它存放的是一维数组第一个元素的地址

	return 0;
}

            

             2>   下标和指针的关系

               如果p是指针变量,则 p[i]   永远等价于 *(p+i),

              *(p+i) 表示的是 地址是(p+i)所指向的元素

                     

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

void f(int* arr, int len)
{
	arr[3] = 88; //arr[3] 等价于 *(arr+3)

}
int main(void)
{
	int a[6] = { 1,2,3,4,5 ,6};
	printf("%d\n", a[3]);   //结果 是 4
	f(a, 6);  //a是数组名称,存放的是第一个元素的地址,类型是int*
	printf("%d\n", a[3]); //结果是  88

	return 0;
}

              3>确定一个一维数组需要的参数

                       数组第一个元素地址   +  数组的长度

               

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

void f(int * arr,int len)  
{
	int i;
	for (i = 0; i < len; i++)
	{
		printf("%d ", arr[i]); //arr[i]等价于*(arr+i),也等价于a[i],也等价于*(a+i)
	}
}


int main(void)	
{
	int a[5] = { 1,2,3,4,5 };
	
	f(a,5);  //a是数组名称,存放的是第一个元素的地址,类型是int*

	return 0;
}

                4>指针变量的运算

                    指针变量不能相加,不能相乘除

                    如果两个指针变量指向的是同一块连续空间中的不同存储单元,则这两个指针变量才                      可以相减

                      

# define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main()
{
	int i = 5;
	int j = 10;
	int* p = &i;
	int* q = &j;
	//p-q没有实际意义
	int a[5];
	p = &a[1];
	q = &a[4];
	printf("p和q所指向的单元相隔%d个单元\n", q - p);
	//结果:p和q所指向的单元相隔3个单元

	return 0;
}

5> 一个指针变量 占多少字节?

  sizeof(数据类型) -----返回值是该数据类型所占的字节数

 例子:sizeof(int)=4               sizeof(char) =1             sizeof(double)=8

 sizeof(变量名)----返回值是该变量所占的字节数

# define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main()
{
	char ch = 'a';
	int i = 99;
	double x = 9.9;
	char* p = &ch;
	int* q = &i;
	double* r = &x;
	printf("%d %d %d\n", sizeof(p), sizeof(q), sizeof(r)); //在64位下,结果是  8,8,8

	return 0;
}

总结:

  •           一个指针变量,无论它指向的变量占几个字节,该变量本身只占4个字节(32位平台)

          (指针的大小在32位平台是4个字节,在64位平台是8个字节)

  •           一个变量的地址是使用该变量首字节的地址来表示的

     三、指针类型

char* 类型的指针是为了存放 char 类型变量的地址。
short* 类型的指针是为了存放 short 类型变量的地址。
int* 类型的指针是为了存放 int 类型变量的地址。

总结:
1.指针的类型决定了指针向前或者向后走一步有多大(距离)。
 2.  指针类型还决定了在指针在进行解应用时,可以访问多少个字节

四 指针运算

1.指针-指针

指针-指针的绝对值,表示2个指针之间元素的个数

备注:指针减去指针的前提是,指向同一块空间的2个指针才能相减

# define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
//方法一
int my_strlen1(char* str)
{
	int count = 0;
	while (*str !='\0')
	{
		count++;
		str++;
	}
	return count;
}

//方法二 指针-指针

int my_strlen2(char* str)
{
	char* start = str;
	while (*str != '\0')
	{
		str++;
	}
	
	return str-start;
}



int main()
{
	int len = my_strlen1("abcdef");
	printf("%d\n", len);

	int len2 = my_strlen2("abcdef");
	printf("%d\n", len2);

	return 0;
}

五 指针与数组

# define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>



int main()
{
	int  arr[10] = { 0 };
	int* p = arr;
	int sz = sizeof(arr) / sizeof(arr[0]);
	int i;
	for (i = 0; i < sz; i++)
	{
		printf("%p------%p\n", &arr[i], p + i);
		
	}
	for (i = 0; i < sz; i++)
	{
		
		//printf("%d ", arr[i]);
		
		//printf("%d ", *(p+i));

		printf("%d ", *(arr+i));


	}

	return 0;
}

六 、野指针

概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)
# define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>

int main()
{

	int* p;
    //P没有初始化,就意味着没有明确的指向
	//一个局部变量不初始化,放的就是随机值
	*p = 10; //非法访问内存,p就是野指针

	return 0;
}

  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值