C语言-09(指针变量)

本文详细介绍了指针变量的概念,包括其本质、地址的定义与运算(偏移和间接运算),以及如何正确地定义、初始化和赋值指针。此外,还讨论了指针在处理字符串常量和传递参数时的应用,强调了正确使用指针的重要性。
摘要由CSDN通过智能技术生成

(内容为学习笔记,如有错误,还望指正,如有遗漏,还望补充) 

1.指针变量

1)指针变量定义

        指针变量的本质是存放地址的变量,变量用来表示逻辑。

        整型变量表示整数,所以变量中存放整数。

        浮点型变量表示小数,所以变量中存放小数。

        指针变量表示地址,指针变量中存放地址。

2)地址的定义

        现实生活中的地址有什么用?用来查找地点。

        内存很大,内存以字节为单位对里面的空间进行编址。在内存中每个字节都有自己唯一的地址。

                        1byte(字节) ======== 8bit(二进制位)

        当我们定义变量的时候,系统会在内存中为变量分配空间。

        当一个变量占多字节时,以地址最小的字节的地址,作为整个变量的地址。

 3)地址运算

a.地址偏移
+ -
//+n  -n 指针就会发生移动,移动n个指针类型变量的长度
#include <stdio.h>

int main()
{
	char a;//定义char类型变量a,char类型占1字节
    //%p是地址的格式符
	printf("%p %p\n", &a, &a+1);//打印a的地址,和a的地址+1  差值是1
	return 0;
}
//每次运行的地址是不一样的,因为变量的地址是系统自动分配的,我们决定不了。但是差值一定是1

重点:地址是有类型的

        不同类型的地址+1后,加的字节数不一样。不同类型的地址,在数据上看不出区别。

        char类型变量,能得到char类型地址,+1加1字节。因为char类型占1字节。 int类型变量,能得到int类型的地址,+1加4个字节。因为int类型占4字节。

        int类型地址,+10,加10*4就是40字节。

b.间接运算(重点)
*  单目运算(一元运算)      乘法* 是二元运算

1. 	间接运算只能对地址运算。
2.	间接运算的运算结果是地址对应的对象本身(itself)!间接运算得到的结果不是数值!!!
#include <stdio.h>

int main()
{
	int a;
	*(&a) = 10;//代码中的()可以不写,我写()的目的是让同学们看的更加醒目
    /*
    *(&a) = 10; 
    间接运算的优先级高,所以先算*(&a),对&a间接运算,得到的结果是变量a本身。
    再进行赋值运算,所以赋值运算符的左值是变量a    a = 10;  所以下面输入a的结果是10
    *(&a) = 10;和a = 10是一样的。
    */
	printf("%d\n", a);
	return 0;
}

4)定义指针变量

int *p;//定义指针变量p
/*
首先*说明p是指针变量,int说明指针变量中存放的地址是int类型的地址。
*/

/*
在C和C++中,出现在声明语句中的符号,都不是运算符,而是用来表达标识符身份的符号!
这样的符号在C语言中有3个
[] 数组  ()函数  *指针变量
*/
    
int a;      //a是整型变量
int a[10];  //a是整型数组
int a();	//a是函数
int* a;		//a是指针变量
a.初始化
int a;
int *p = &a;//给p初始化,这里的*不是运算符,而是表达p是指针变量身份的符号。
b.赋值
int a;
int *p;
p = &a;//对指针变量p赋值。
c.举例说明
#include <stdio.h>

int main()
{
	int a;
	int* p = &a;//使用a的地址给p赋值,p指向a 
	*p = 10;
    /*
    先算*,后算=
    *p运算得到变量a本身,因为p中的数据是a的地址,对变量的运算就是对变量中的数据的运算。
   	所以=的左值是a,  a = 10
    */
	printf("%d\n", a);//10
	return 0;
}

5)输出指针变量

%p (推荐) 
%x
%#x

6)指针变量的意义

a.错误用法
#include <stdio.h>

void fun(int b);

//首先这里的a是实参,b是参数列表中的形参
int main()
{
	int a;
	fun(a);
	printf("%d\n", a);//未知数
	return 0;
}

//使用main中的a初始化形参b
void fun(int b)
{
    //给形参b赋值和main中的实参a没有关系
	b = 10;
}
b.正确用法
void fun(int* b)//使用main中a的地址初始化形参b,b指向main中的a
{
	*b = 10;//*b运算得到main中的a本身,所以这里是给main中的a赋值
}

int main()
{
	int a;
	fun(&a);
	printf("%d\n", a);//10
	return 0;
}

7)字符串常量指针

        使用字符串常量给指针变量赋值,是将字符串常量的首地址赋值给指针变量。

        此时指针变量间接运算得到字符串常量中的第一个字符常量本身。

        字符串常量在内存中是连续存放的。

char s1[] = "hello world";//s1是字符类型的数组,使用字符串常量初始化s1
char* s2 = "hello world"; //s2是字符类型指针,存放了字符串常量的首地址,是h的地址。

s1[0] = 'a';//正确,数组的元素都是变量,可以对变量赋值
*s2 = 'a';//错误  s2中的数据是常量的地址,所以*s2得到常量本身,不能对常量赋值

        32位(32个二进制位)操作系统,地址是4字节;64位(64个二进制位)操作系统,地址是8字节。

        无论什么类型的地址,地址本身只占4字节(64位系统中8字节)。所以指针变量的大小就是4字节(64位系统中8字节)

int* p;//没有被初始化的int类型指针变量
char* p2;//没有被初始化的char类型指针变量
char* p3 = "hello world";//被初始化的char类型指针变量
printf("%d %d %d\n", sizeof(p), sizeof(p2), sizeof(p3));// 4 4 4

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值