😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
🤣本文内容🤣:🍭介绍标准C语言的32个关键字🍭
😎金句分享😎:🍭有机会一定要试试,其实试错的成本并不高,而错过的成本很高🍭
C语言32个关键字详解(1):数据类型部分(char、short、int、long、float、double、struct、union、enum、void)
C语言32个关键字详解(2):修饰类型部分(auto、signed、unsigned、static、extern、const、register、volatile)
C语言32个关键字详解(3):结构语句部分(if、else、switch、case、default、do、while、for、break、continue、return、goto)
C语言32个关键字详解(4):其他(typedef、sizeof)
目录
🎄一、概述
C语言的关键字有32个,我将它主要分成下面四个方面来介绍。
功能 | 关键字 |
---|---|
类型(10个) | char、short、int、long、float、double、struct、union、enum、void |
修饰类型(8个) | auto、signed、unsigned、static、extern、const、register、volatile |
结构语句(12个) | if、else、switch、case、default、do、while、for、break、continue、return、goto |
其他(2个) | typedef、sizeof |
前面介绍了char、short、int、long、float、double、struct、union、enum、void、auto、signed、unsigned、static、extern、const、register、volatile、 if、else、switch、case、default、do、while、for、break、continue、return、goto
;
这篇文章主要介绍最后两个关键字typedef、sizeo
。
🎄二、typedef 关键字
✨2.1 typedef 给类型取别名
从 typedef
的名字来看,会以为它是定义新的数据类型,但实际上 typedef
的真正意思是给一个已经存在的数据类型(注意:是类型不是变量)取一个别名,而非定义一个新的数据类型。常用来给基本类型、指针类型、函数指针取别名;
常见的用法:
1、给基本数据类型重命名,代码如下:
typedef signed char int8_t;
typedef short int16_t;
typedef int int32_t;
typedef long long int64_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
uint64_t u64_i = 0; // 等同于 unsigned long long u64_i = 0;
2、给结构体、结构体指针类型取别名:
typedef struct student
{
//...code
}Stu_st, *Stu_pst;
Stu_st stu; // 等同于 struct student stu;
Stu_pst pStu; // 等同于 struct student* pStu;
3、给函数指针类型取别名:
typedef unsigned int (*fn_callback)(void*,void*);
fn_callback fn_callback; // 定义一个函数指针 fn_callback
✨2.2 typedef 的类型 和 const 一起使用
首先,我们知道
const
在类型前或后去修饰一个变量时,效果是一样的。
如:const int i;
和int const i;
两个语句都是表示变量i
的值是只读的,不允许被改变。
而
const
在*
前面表示修饰的指针指向的对象是只读的,const
在*
后面表示指针是只读的,如:
const int * pI;
表示pI
指向的对象的值是只读的,不能被改变;
int * const pI;
表示pI
变量的值是只读的,不能被改变;
那么下面的代码中,先将int *
重命名为 pInt
。请问 const_pInt
和 pInt_const
分别表示哪些是只读的?
typedef int * pInt;
const pInt const_pInt;
pInt const pInt_const;
可能你会认为const_pInt
表示指针指向的对象是只读的,而pInt_const
表示指针本身是只读的。答案是,const_pInt
和 pInt_const
都是表示指针本身是只读的。因为编译器单纯地把pInt
当作一个类型来处理,所以它只会限制变量只读,不可修改。
可以用下面代码测试验证:
// typedef.c
#include <stdio.h>
typedef int * pInt;
int main()
{
int i=0, j=0;
const pInt const_pInt = &i;
pInt const pInt_const = &i;
//const_pInt = &j; //报错:assignment of read-only variable ‘const_pInt’
//pInt_const = &j; //报错:assignment of read-only variable ‘pInt_const’
*const_pInt = 1;
*pInt_const = 2;
return 0;
}
原文链接:https://blog.csdn.net/wkd_007/article/details/133997095
✨2.3 typedef 的类型 和 #define 的区别
如果将上面的typedef int * pInt;
替换成#define pInt int*
,const_pInt
和 pInt_const
分别表示哪些是只读的?
答案是,const_pInt
表示指针指向的对象是只读的,而pInt_const
表示指针本身是只读的。因为宏定义会在预处理阶段替换成int*
,就变成了const int * const_pInt;
和int * const pInt_const;
可以用下面的代码测试验证:
//typdef_define.c
#include <stdio.h>
#define pInt int*
int main()
{
int i=0, j=0;
const pInt const_pInt = &i;
pInt const pInt_const = &i;
const_pInt = &j;
//pInt_const = &j; //报错:assignment of read-only variable ‘pInt_const’
//*const_pInt = 1; //报错:assignment of read-only location ‘*const_pInt’
*pInt_const = 2;
return 0;
}
因为宏定义只是进行简单的字符串替换,所以宏定义的指针类型,每次只能成功定义一个指针变量。
例如:下面代码中,pI
变量是int*
类型的,而i
变量则是int
类型的;
而pS
、pSh
都是short *
类型的。
#define pInt int*
typedef short * pShort;
pInt pI,i;
pShort pS,pSh;
🎄三、sizeof 关键字
✨3.1 sizeof 是关键字,不是函数
sizeof 关键字常被误以为是函数,实际上,它是一个关键字。作用是在编译时计算给定类型或变量的大小,并返回占用空间大小,返回的值是long unsigned int
类型的。
在计算指定类型大小时,需要加()
,计算指定变量的大小时可以不用()
,下面代码中,sizeof(int), sizeof(i), sizeof i
都是正确的,如果写成sizeof int
就是错误的,因为返回的值是long unsigned int
,用%lu
打印。
#include <stdio.h>
int main()
{
int i = 0;
printf("sizeof(int)=%lu, sizeof(i)=%lu sizeof i = %lu\n",sizeof(int), sizeof(i), sizeof i);
return 0;
}
注意:
1、sizeof i
这个语句是正确的,就可以证明 sizeof
是关键字而不是函数,因为不能这样调用;
2、一般情况下,使用sizeof
时,建议带上()
;
✨3.2 sizeof 与指针、数组的使用
sizeof 关键字计算指针的值时,在32位系统永远返回4,在64位系统永远返回8;
int *p = NULL;
sizeof(p)的值是多少?
sizeof(*p)呢?
int a[100];
sizeof (a) 的值是多少?
sizeof(a[100])呢? //请尤其注意本例。
sizeof(&a)呢?
sizeof(&a[0])呢?
sizeof((&a)[0])呢?
int b[100];
void fun(int b[100])
{
sizeof(b);// sizeof (b) 的值是多少?
}
阅读上面代码,试着判断各个sizeof
的值是多少?答案在下文给出,可以自己先判断,看看能否准确!!!
在判断sizeof
的值时,要清楚指定的变量是什么类型?
以32位系统为例,只要是指针,其sizeof
的值就是4;
只要是数组名,sizeof
大小就是整个数组的大小;
只要是数组元素,sizeof
大小就是单个数元素的大小;
如果数组作用函数参数,那么sizeof(数组名)
的大小则等于指针的大小;
答案:在64位系统运行下面代码,打印的答案如下:
sizeof(p)=8 sizeof(*p)=4
sizeof(a)=400, sizeof(a[100])=4, sizeof(&a)=8, sizeof(&a[0])=8, sizeof((&a)[0])=400
sizeof(b)=8
// sizeof_arr.c
#include <stdio.h>
void fun(int b[100])
{
printf("sizeof(b)=%lu\n",sizeof(b));
}
int main()
{
int *p = NULL;
printf("sizeof(p)=%lu sizeof(*p)=%lu\n",sizeof(p),sizeof(*p));
int a[100];
printf("sizeof(a)=%lu, sizeof(a[100])=%lu, sizeof(&a)=%lu, sizeof(&a[0])=%lu, sizeof((&a)[0])=%lu\n",
sizeof(a), sizeof(a[100]), sizeof(&a), sizeof(&a[0]), sizeof((&a)[0]));
int b[100];
fun(b);
return 0;
}
✨3.2 sizeof 与复杂类型
先看看下面这些变量的类型是什么?
char a[10][20];
char (*pa)[5];
char (*p_fun)(char *);
int (*(*pa_fun)[5])(char *);
把变量名去掉,得到的就是类型了,对于类型表示什么,在后面讲指针的文章会介绍。我们把这些复杂的类型给到sizeof
,居然可以计算出类型占用的内存大小,看例子:
#include <stdio.h>
int main()
{
char a[10][20];
char (*pa)[5];
char (*p_fun)(char *);
int (*(*pa_fun)[5])(char *);
printf("sizeofType [%lu] [%lu] [%lu] [%lu]\n",sizeof(char [10][20]), sizeof(char (*)[5]),sizeof(char (*)(char *)),sizeof(int (*(*)[5])(char *)));
printf("sizeof Val [%lu] [%lu] [%lu] [%lu]\n",sizeof(a), sizeof(pa),sizeof(p_fun),sizeof(pa_fun));
return 0;
}
运行结果:
🎄四、总结
本文主要介绍C语言的两个关键字typedef、sizeof
,结合前面的30个,C语言的32个关键字全部介绍完了。
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁