三、隐式类型转换
隐式类型转换的原因:参与计算的数据如果类型不同无法直接进行计算。
整型提升:有符号的补符号位,无符号的补0(符号位为最外面的那位)
unsigned char 8位数据位,范围在0-255,所以-2(11111110)时,变成254;同理-1(11111111)时,变成255;最后减到0时,不满足循环条件,for停止。刚好173次。 (7 4 1 ==> 共(7-1)/3+1=3次,1-3=-2,即254,继续循环)
254 251 … 5 2 ==> 共(254-2)/3+1=85次(2-3=-1,即255,继续循环)
255 252 … 6 3 ==> 共(255-5)/3+1=85次(3-3=0,退出循环) 所以总共173次
指针
指针变量是个变量,指针本身是个地址,用于存放内存单元的地址。
指针时用来存放地址的,指针类型的变量无论指向目标是什么类型,指针本身在32位平台所占大小都为4个字节,在64位平台是8个字节 。
#include
int main()
{
int a = 10;//在内存中开辟一块空间,左值为空间,右值为内容
int *p = &a;//type* p
//这里我们对变量a,取出它的地址,可以使用&操作符。
//将a的地址存放在p变量中,p就是一个之指针变量。
return 0;
}
一、指针的解引用
1、对指针的解引用只能看到sizeof(type)个字节的数据;
2、按字节为单位,数据有高权值和低权值之分,地址有低地址和高地址之分;
3、数据低权值位在低地址处即为小端存储,反之则为大端存储。
(“小小小”)
二、野指针
概念
指向的位置是不可知的指针。
规避
1、指针在定义时就进行初始化;
2、避免指针越界(eg:注意循环时循环次数的限制);
3、指针使用完即进行指针指向空间释放;
4、避免返回局部变量的地址;
5、指针使用前检查其有效性。
三、指针运算
1、指针±整数,等价于±sizeof(type);
2、指针-指针,两指针必须同一类型,一般用于数组与字符串求其两地址间相隔的单元格数,否则无效(指针+指针为非法操作);
3、指针的关系运算。
4、指针和数组都可以用中括号或者解引用(二者互通)。
四、字符指针
1、字符指针
在指针的类型中我们知道有一种指针类型为字符指针 char* ;
一般使用方法
int main()
{
char ch = 'w';
char *pc = &ch;
*pc = 'w';
return 0;
}
用char*指针指向字符串
int main()
{
const char* pstr = "hello bit.";
printf("%s\n", pstr);
return 0;
}
//上述代码中把字符串hello bit.的首地址放入了指针中
需注意字符串可以以字符数组的形式给出,但是此时的字符数组附有存储功能,而字符指针具有常量属性,指向的是常量区的内容,因此不可被修改,可以写作:
const char* str="hello world";//从上图表示不可被修改
1
也正因为这个原因 C/C++会把常量字符串存储到单独的一个内存区域,当几个指针指向同一个字符串的时候,他们实际会指向同一块内存。但是用相同的常量字符串去初始化不同的数组的时候就会开辟出不同的内存块。
#include
int main()
{
char str1[] = "hello world.";
char str2[] = "hello world.";
const char *str3 = "hello world.";
const char *str4 = "hello world.";
if(str1 ==str2)
printf("str1 and str2 are same\n");
else
printf("str1 and str2 are not same\n");
if(str3 ==str4)
printf("str3 and str4 are same\n");
else
printf("str3 and str4 are not same\n");
return 0;
}
在这里插入图片描述
2、const知识点
在此说一下const的一些知识点:
① const修饰的变量不能被直接修改,但是可以通过指针在进行类型强转来修改(只是可以但是完全没必要);
② const修饰指针,表示不可以通过指针来修改所指目标;
③ const能用则用,会很好的保护数据,
const的作用:
① 写给编译器看,提前发现可能错误的修改;
② 写给程序员看,提示该变量不建议修改。
const int* p=&a;
*p = 20; //错误,*p所指的值不可以修改
p = &n;//正确,*p的指向可以修改
int* const q = &m;
*q = 20;//正确,此时const修饰的是q,此时q所指向的值可以进行修改
q = &t;//错误,由于const修饰的是q,此时的q的指向不可以进行修改
const int a=10; //若const a=10,编译器也会默认为a是int类型的
int *P=(int*)&a; //注意需要强制&a前需要加int*类型强制类型转换(&a的原本类型为const int*)
*P=12;