(内容为学习笔记,如有错误,还望指正,如有遗漏,还望补充)
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