返回

学习随记_3

发布时间:2022-09-19 07:23:44 359

·操作符


-算术操作符

/ 可以对浮点数进行计算

% 只能对整型计算


-移位操作符


右移操作符 :

1.算术右移

右边丢弃,左边补原符号位(正为0,负为1)

n/2 等价于 n>>1

2.逻辑右移

右边丢弃,左边补0


-整数的二进制表示

 原码,反码,补码

 -在内存中储存的是补码

-1:

原码10000000000000000000000000000001

反码11111111111111111111111111111110

补码11111111111111111111111111111111(反码加1)

 -正整数的原码、反码、补码相同


左移操作符:

左边丢弃,右边补0

·对于移位操作符,不要移动负数位,这个是标准未定义的

·位操作符 -操作对象必须为正整数

& 按位与 只要有一个为0即为0,同时为1才为1

| 按位或 只要有一个1即为1

^按位异或 相同为0,相异为1


·赋值操作符


-复合操作符


·双目操作符 -有两个操作数


·单目操作符 -仅有一个操作数

!逻辑反操作 :真变成假,假变成真

-取负值

+取正值

& 取地址

*解引用操作符

sizeof( )计算变量/数组/内存所占内存空间的大小,单位是字节

-sizeof中的操作不会对参数产生实际影响

~ 按位取反

++,前置++,先++后使用 ;后置++,先使用后++

--,前置--,后置--

-printf函数中的操作会对参数产生实际影响

(类型)强制类型转换

-数组传参时穿的是首元素的地址

·双目操作符

-逻辑操作符

逻辑与 &&

-若&&左边出现假,整体直接为假,右边不再计算

逻辑或 | |

-若   | |左边出现真,整体直接为真,右边不再计算

 

·条件操作符(三目操作符)

exp1?exp2:exp3


·逗号表达式

-从左到右依次计算,整个表达式的结果为最后一个表达式的结果

//逗号表达式
#include
int main(void)
{
int a = 1;
int b = 2;
int d = 1;
//
int c = 0;
if (a=b+2,b=a+3,d>0)
{
c = a + b;
}
printf("c=%d\n", c);
return 0;
}


·下标引用操作符

-操作数:一个数组名+一个索引值


·函数调用操作符 ( )

操作数:函数名和各个参数


·结构体类型


·结构体的传参

-传值调用

-传址调用

-元素调用


·隐式类型提升


--整型提升(对于小于整型的类型)

-若计算式一个表达式不能达到整型的大小,该表达式会发生整型提升

-提升方式:按符号位进行提升,若无符号直接补0

-提升至32bit

-意义:便于cpu运算

//整型提升
#include
int main(void)
{
char a = 3;
//00000000000000000000000000000011
//00000011
char b = 127;
//00000000000000000000000001111111
//01111111
char c = a + b;
//对a,b进行整型提升
//00000000000000000000000000000011(a)
//00000000000000000000000001111111(b)
//相加
//00000000000000000000000010000010
//10000010(c)
//对c进行整型提升
//11111111111111111111111110000010(补码)
//11111111111111111111111110000001
//10000000000000000000000001111110
//-126 (int)c
printf("c=%d\n", c);
}


--算数转换

-小类型转换为大类型


·操作符的相关属性

-优先级

-结合性

-是否控制运算顺序


·在求值时要确保表达式的求值顺序是唯一的



·指针

-指针变量用来存放地址

-指针就是地址


-每个地址 标识 一个字节

-32位机器地址需要4个字节来存储


·指针类型的意义


-指针类型决定了指针进行解引用操作时能够访问空间的大小

int* p *p能够访问4个字节

char* p *p能够访问1个字节

-指针类型决定了指针向前或向后走一步的距离

int* p:p+1--->4

char* p:p+1--->1

学习随记_3_整型提升


·野指针

-指针指向的位置不可知(随机的,不正确的,没有明确限制的)

//野指针_1
#include
int main(void)
{
int* p;//局部变量未初始化默认是随机值
*p = 20;
return 0;
}

//野指针_2
#include
int main(void)
{
int arr[10] = { 0 };
int* p = arr;
int i = 0;
for ( i = 0; i < 12; i++)//超出arr的范围的指针是野指针
{
//*(p + i) = 1;

//*p = i;
//p++;

*p++ = i;//与前面两行代码效果相同
}
}

//野指针_3
#include

int* test()
{
int a = 10;//申请一块内存存放局部变量a
return &a;//存放a的内存被释放
//int arr[] = { 0 };
//return arr;//数组同理
}

int main(void)
{
int* p = test();//离开test函数时存放a的内存被释放
*p = 20;//指向了一块被释放的内存
}


产生原因:

1.指针未初始化

2.指针越界访问

3.指针指向的内存释放

-局部变量不初始化默认是随机值


-规避野指针

1.初始化指针

2.小心指针越界

3.设置已释放的指针为NULL

4.使用之前检查有效性(NULL指针不能使用)


·模拟实现strlen函数计算字符串长度的三种方法

#define _CRT_SECURE_NO_WARNINGS 1


//模拟strlen函数求字符串长度

//1.计数器
//#include
//
//int my_strlen(char* str)
//{
// int count = 0;
// while (*str != '\0')
// {
// count++;
// str++;
// }
// return count;
//}
//
//int main(void)
//{
// char arr[] = "hello";
// int len = my_strlen(arr);
// printf("len=%d\n", len);
// return 0;
//}

//2.函数递归
//#include
//
//int my_strlen(char* str)
//{
// if (*str != '\0')
// {
// return 1 + my_strlen(str + 1);
// }
// else
// {
// return 0;
// }
//}
//
//int main(void)
//{
// char arr[] = "hello";
// int len = my_strlen(arr);
// printf("len=%d\n", len);
// return 0;
//}

//3.指针运算
#include

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

int main(void)
{
char arr[] = "hello";
int len = my_strlen(arr);
printf("len=%d\n", len);
return 0;
}




特别声明:以上内容(图片及文字)均为互联网收集或者用户上传发布,本站仅提供信息存储服务!如有侵权或有涉及法律问题请联系我们。
举报
评论区(0)
按点赞数排序
用户头像
精选文章
thumb 中国研究员首次曝光美国国安局顶级后门—“方程式组织”
thumb 俄乌线上战争,网络攻击弥漫着数字硝烟
thumb 从网络安全角度了解俄罗斯入侵乌克兰的相关事件时间线
下一篇
C语言——操作符(中) 2022-09-19 06:55:27