c语言指针笔记

关键字static

c语言中的static关键字是用来修饰变量和函数的,可以分为以下三种情况

1.修饰局部变量--静态局部变量

c语言中的局部变量和静态局部变量在内存中的存储位置。

 static修饰局部变量的时候,改变了局部变量的存储类型,但是作用域还是不变的;本来一个局部变量是存储在栈区的,被static修饰的局部变量是存储在静态区的,存储在静态区的变量出了作用域变量也不会销毁,所以生命周期较长,即static修饰的局部变量、全局变量的生命周期和程序的生命周期是一样的。

#include<stdio.h>
void fun() {
	static n = 1;  //在汇编文件中没有该句对应的汇编语句
	n++;
	printf("%d\n", n);
}
int main() {
	fun();  // 2 ,只有第一次调用fun()函数时 static n = 1;才会执行,然后该句在静态区中创建一个n变量
	fun(); // 3 , 该句会直接执行n++,去静态区找到n变量,然后将n++,因为静态区的变量不会在出作用域时被销毁
	//所以 n = 2,当执行n++后,n变为3。
	return 0;
}
2.修饰全局变量--静态全局变量

val为add.c文件中定义的全局变量,而全局变量有外部链接属性,所以在test.c编译后的链接步骤中可以链接到add.c文件中使用val变量。而static修饰全局变量的时候,改变了全局变量的链接属性;本来一个全局变量具有外部链接属性的,但是被static修饰之后就变成了内部链接属性。这是static修饰的全局变量只能在本源文件(.c)中使用,其他文件无法再使用到。

 

 3.修饰函数--静态函数

static修饰函数和修饰全局变量有相似的作用,当在Add.c中定义一个函数时,在test.c中使用extern声明后就可以使用。但是如果Add.c中的函数被static修饰后,就不能在test.c中使用了。

 其实static修饰函数和修饰全局变量是类似的,一个函数本来也是具有外部链接属性的。但是当被static修饰的时候,外部链接属性就变成了内部链接属性,这个函数就只能在本源文件内部使用了,其他文件不能再使用了。

 

 #define定义常量和宏

#define可以定义常量

#define定义的常量在预处理文件中都被替换为代表的值。

#include<stdio.h>
#define NUM 100  //定义int型
#define STR "string"  //定义字符串
int main() {
	int a = NUM;  //在预处理文件中为 int a = 100;  直接将NUM都替换为100
	char arr[10] = STR;  //在预处理文件中为 char arr[10] = "string";
	printf("%d\n", NUM);  //都会将NUM替换为100
	printf("%s", STR);  //都会将STR替换为字符串"string"

	return 0;
}
#define定义宏
#include<stdio.h>
//#define定义的宏是有参数的
#define ADD(x,y) ((x)+(y))  //尽量加括号,以保证使用宏时不会产生歧义
int main() {
	int res = ADD(2, 3);  //在预编译文件中会变为 int res = ((2) + (3));
	printf("%d", res);

	return 0;
}

指针

内存和内存单元

内存是电脑上特别重要的存储器,计算机中所有程序的运行都是在内存中进行的 。 所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。 为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。

指针

指针就相当于地址,我们直到int a 就是用来存储一个int 型整数的,所以int* pa就是用来存储一个int* 型的指针(地址)的。

#include<stdio.h>
int main() {
	int a = 10;
	int* pa = &a;   //& -- 取地址操作符
	*pa = 20;   //* -- 解引用操作符
	printf("%d", a);
	//指针变量pa就是用来存放地址的一种变量
	return 0;
}

内存会被划分为小的内存单元,一个内存单元的大小是1个字节。

每个内存单元都有编号,这个编号也被称为:地址\指针。

地址\指针据可以存放在一个变量中,这个变量被称为指针变量

通过指针变量中存储的地址,就能找到指针指向的空间,并且可以取出或者修改该空间中存的数据。

 任何数据放在指针变量里面,都会被解析为地址,如果指针变量里面存了3,即int *pa = 3,则*pa=5就会将0x 03 00 00 00当成地址解析,并且会将该地址里面存储的的数据变为5。

指针变量的大小

指针变量是用来存放地址的,地址的存放需要多大空间,指针变量的大小就应该是多大。

32位机器 -- 支持32位虚拟地址空间 - 产生的地址就是32bit位 -- 需要32bit的空间存储

即4byte -- 所以32位机器中指针变量的大小就是4byte。(因为指针变量就是存储地址的)

64位机器 -- 支持64位虚拟地址空间 -- 产生的地址就是64bit位 -- 需要64bit的空间存储

即8byte -- 所以64位机器中指针变量的大小就是8byte

#include<stdio.h>
int main() {
	int a = 10;
	char ch = 'a';
	double d = 3.3;
	int* pa = &a;
	char* pch = &ch;
	double* pd = &d;

	printf("%d\n", sizeof(pa));  //32位机器为4,64位机器为8
	printf("%d\n", sizeof(pch));  //32位机器为4,64位机器为8
	printf("%d\n", sizeof(pd));   //32位机器为4,64位机器为8

	return 0;
}

结构体

c语言中的内置类型有时候不足以存储我们的数据,所以我们可以根据结构体创建自己想要的类型,即自定义类型。

#include<stdio.>
//描述一个学生
//创建一个学生类型
struct Stu {
	char name[20]; //成员
	int age;  //成员
	char sex[5];
	double score;
};

int main() {
	struct Stu s1 = { "张三",20,"男",90.5 };  //初始化一个struct Stu类型的变量
	struct Stu s2 = { "如花",30,"女",97.5 };
	//输入结构体成员的数据
	scanf("%s %d %s %lf", s1.name, &(s1.age), s1.sex, &(s1.score)); //因为成员name和sex为数组,所以数组名就是元素首地址
	//结构体成员访问操作符 . 和 ->
	//结构体变量.结构体成员
	printf("%s %d %s %lf\n", s1.name, s1.age, s1.sex, s1.score);

	struct Stu* ps1 = &s1;  //将结构体s1的地址存储到指针变量ps1中
	//结构体指针(地址)->结构体成员
	printf("%s %d %s %lf\n", ps1->name, ps1->age, ps1->sex, ps1->score);
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值