初识指针
计算机内存
内存是电脑上特别重要的存储器,计算机中程序的运行都是在内存中进行的 。 所以为了有效的使用内存,就把内存划分成一个个小的内存单元,每个内存单元的大小是1个字节。 为了能够有效的访问到内存的每个单元,就给内存单元进行了编号,这些编号被称为该内存单元的地址。
变量是存放在内存中的,每个内存都会拥有一个地址,所以每个变量也会有一个地址,如何取出变量储存在内存中的地址呢,如下代码
#include <stdio.h>
int main()
{
int a = 900000000;
printf("%p",&a);
return 0;
}
这里的&a就是取出a的地址,而要打印地址呢需要用到%p
可以看到输出的结果为
就是对应的a存放的地址,我们在调试->窗口->内存中随意选择一个内存既可以看到a存放的值是否在其中
输入对应地址以后可以看到0000005790DDF994中显示了00e9a435,我们知道int占用的长度为四个字节,我们输入900000000进去后得到的2进制数就是0011 0101 1010 0100 1110 1001 0000 0000相对应的16进制数就是35A4 E900存放在内存中,内存中最后一个字节存放的是高位,第一个字节存放的是低位
指针大小
指针的大小取决于计算机地址线的多少,如果是32位的计算器,那么如果要遍历寻址需要有4个字节的空间,因此32位计算器的指针大小为4字节,相对应的,如果是64位计算器的话需要8字节。
结构体
结构是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。如何声明一个结构体呢?比如我们有一个学生,我们想声明他的姓名年龄和体重,我们可以按照下面的代码声明这样一个学生
#include <stdio.h>
struct stu
{
char name[ 20 ];
int age;
double weight;
};
int main()
{
stu s = { "azure",18,78.77 };
printf("name:%s\nage:%d\nweight:%lf\n", s.name, s.age, s.weight);
return 0;
}
如果我们想加入一个学生s,他的姓名年龄体重都已知,我们就可以按照主函数的形式写出
那如何获取学生s的信息呢?在输出时如果我们声明了结构体的姓名可以按照结构体的类型输出就行,只不过要多在后面加入具体输出的目标是什么,如我们要输出的是s同学的姓名即可 s.name,对应的是字符串所以在printf内部用%s来输出可以看到这个程序运行出的结果为:
另外,指针变量也是可以用来储存结构体的,调用有两种方式,具体可以看以下代码:
#include <stdio.h>
struct stu
{
char name[20];
int age;
double weight;
};
int main()
{
stu s = { "azure",18,78.77 };
stu* ps = &s;
printf("name:%s\nage:%d\nweight:%lf\n", s.name, s.age, s.weight);
printf("name:%s\nage:%d\nweight:%lf\n", (*ps).name, (*ps).age, (*ps).weight);
printf("name:%s\nage:%d\nweight:%lf\n", ps->name, ps->age, ps->weight);
return 0;
}
指针的两种调用方式输出的结构均相同,输出如下:
putchar和getchar的使用
getchar为在缓存区输入一个字符,putchar则相反,为缓存区输出一个字符,要注意,如果scanf函数输入了一串数字再打回车键,将判定回车键前的一串数字赋值到了scanf要赋值的变量,而\n这个字符仍然留在缓存区,我们可以看看以下两个例子,可以看出来如果不将缓存区多余的\n吸收掉程序将无法运行
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int main()
{
int a = 0;
char b;
while (a != 123456)
{
printf("请输入一个六位数密码:");
scanf("%d", &a);
printf("\n请确认你输入的密码,输入Y/N:");
b = getchar();
if (b == 'Y')
{
if (a != 123456)
printf("您输入的密码错误\n");
else
printf("恭喜您输入正确");
}
else
printf("请重新确认\n");
}
return 0;
}
要解决此类问题我们可以再再上面加个getchar,程序即可直接运行
if else 及 switch选择语句
if else的语法我们肯定都不陌生了,但是如果有一种情况如下,输出的数应该是多少呢?
这串代码的输出结果居然是未成年,按理来说如果第一个a=60满足条件应该进入if底下if (a <= 30)的判断,不满足所以应该什么都不输出才对,但是呢其实这里的else对应的是第二个if,所以当不满足a<=30的时候直接输出了未成年,虽然说这里看起来else和第一个if对应才是,但是else的对应 规则是最近的if。
break及continue在while循环和for循环的运用
break和continue的在两个循环的语法逻辑其实是类似的,break的作用就是跳出循环,continue的作用就是结束本次循环进入下一轮的循环,如下面对应的代码
#include <stdio.h>
int main()
{
int i = 0;
while (i < 10)
{
if (i == 5)
break;
printf("%d", i);
i++;
}
return 0;
}
此代码输出为01234
#include <stdio.h>
int main()
{
int i = 0;
while (i < 10)
{
if (i == 5)
continue;
printf("%d", i);
i++;
}
return 0;
}
我们可以看到这串代码的输出虽然不输出了,但是程序还一直在运行,只要是当i=5的时候,程序进入了下一个循环此时并未执行下面两行的i++,以此反复,i的值永远都是5,而主函数并未有返还的值,所以这个代码不会结束也不会输出。同理我们可以看看for循环中break和continue的运用
#include <stdio.h>
int main()
{
int i;
for (i = 0; i < 10; i++)
{
if (i == 5)
break;
printf("%d", i);
}
return 0;
}
#include <stdio.h>
int main()
{
int i = 0;
for (i = 0; i < 10 ; i++)
{
if (i == 5)
continue;
printf("%d", i);
}
return 0;
}C
不同的是第二段代码输出的结果仅仅是少一个5而已,因为程序运行到i=5的时候便进行下一次循环了,此时for循环中每次循环i都会增加,所以下一次循环的时候i=6,因此依次打印6-9。