使用C语言的第二天

欢迎使用C语言

C存储类

存储类定义 C 程序中变量/函数的范围(可见性)和生命周期。这些说明符放置在它们所修饰的类型之前。以上是学术性语言,简单的说就是形容词。

auto

默认为auto。使用auto 定义一个变量,在C语言中可以不初始化,编译器会使用一个随机值。
C++中的auto关键字是一个类型说明符,通过变量的初始值或者表达式中参与运算的数据类型来推断变量的类型。
auto val = 5.2f; //编译器会根据初始化的值来推断val的数据类型为flaot,但要注意如果去掉f则编译器会认为val为double型变量

编程时通常需要把表达式值式赋给变量,这就要求在声明变量时清楚的知道表达式的类型。
auto只能用于函数内,因此只能修饰局部变量。

register

register 存储类用于定义存储在寄存器中,这意味着变量的最大尺寸等于寄存器的大小(通常是一个词)。
定义这个变量适用于频繁使用某个变量,以加快运行速度,因为保存在寄存器中,省去了从内存中调用,要注意定义了这个变量后,不能取地址!!就是不能对它应用一元的’&'运算符(因为它没有内存位置)。

static

static 存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。因此,使用 static 修饰局部变量可以在函数调用之间保持局部变量的值,也就是说,只初始化了一次,后面调用的是已经改变的值。
第二种,static 修饰符也可以应用于全局变量。当 static 修饰全局变量时,会使变量的作用域限制在声明它的文件内。全局声明的一个 static 变量或方法可以被任何函数或方法调用,前提是这些方法出现在跟 static 变量或方法同一个文件中。

while和do…while

 while(count--){}:意思就是先执行{}循环体,再count自减。
 while(--count){}:意思就是先count自减,再执行循环体。
 do-while循环与while循环的不同在于:它会先执行{}里面的循环体,然后再判断表达式是否为真,如果为真则继续循环;如果为假,则终止循环。因此,do...while 循环至少要执行一次{}里面的循环体。

extern

extern 存储类用于提供一个全局变量的引用,全局变量对所有的程序文件都是可见的(概述性理论)。当使用 extern 时,对于无法初始化的变量,会把变量名指向一个之前定义过的存储位置

当有多个文件且定义了一个可以在其他文件中使用的全局变量或函数时,可以在其他文件中使用 extern 来得到已定义的变量或函数的引用。可以这么理解,extern 是用来在另一个文件中声明一个全局变量或函数
extern 修饰符通常用于当有两个或多个文件共享相同的全局变量或函数。

总结

auto只能在函数内部使用。
//局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。
register代表了寄存器变量,不在内存中使用。
static代表了静态变量,存在作用域。
//静态变量会被放在程序的静态数据存储区(全局可见)中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
extern是全局变量,对程序中所有文件中都可用。
//把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。

A.若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
B.若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
C.设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题,因为他们都放在静态数据存储区,全局可见;
D.如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带"内部存储器"功能的的函数)
E.函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。

auto 普通局部栈变量,是自动存储,这种对象会自动创建和销毁 ,建议这个变量要放在堆栈上面,调用函数时分配内存,函数结束时释放内存。

自增自减Demo

#include<stdio.h>
int main()
{
int c;
int a=10;
c=a++;
printf("先赋值后运算:\n");
printf("1-c的值是%d\n",c);
printf("2-a的值时%d\n",a);
a=10;
c=a--;
printf("3-c的值时%d\n",c);
printf("4-a的值时%d\n",a);

printf("先运算后赋值:\n");
a=10;
c=++a;
printf("5-c的值是%d\n",c);
printf("6-a的值是%d\n",a);
a=10;
c=--a;
printf("7-c的值是%d\n",c);
printf("8-a的值是%d\n",a);
}

自我总结

if()中的()填的是判断语句,语句中bool型,只有真假之分。
else后面可以不写判断语句。
if else{}里面的需要加“;”.
可以多个if,不写else。
逻辑与&&,逻辑非||。
auto值后面直接改就行。

位运算符

按位与:&
按位或:|
按位异或:^ 同假异真
按位取反:~,先求正数的补码,前面填上零,皆是符号位;全部取反减一;除符号位,再次取反,得到数字。直观显示的是每位取反。
二进制左移:<<,左边二进制位舍弃,右边二进制位补零。
二进制右移:>>,正数右移,右移二进制位舍弃,左边补零。负数右移,右移二进制位舍弃,左边补1。
移动的符号位和数据位。

小结

sizeof(),返回变量的大小,&返回变量的实际地址。*指向一个变量。

优先级

优先级从高到低------后缀(从左到右),一元(“sizeof”,’+’——正号,’-’——负号,’!’, ‘++’, ‘–’ , ‘~’——位非,返回数字的非。从右到左),乘除(从左到右),加减(从左到右),移位(从左到右),关系(从左到右),相等(==!=从左到右),位与(从左到右),位异或(从左到右),位或(从左到右),逻辑与(从左到右),逻辑或(从左到右),条件(从右到左),赋值(从右到左),逗号(从左到右)。

运算符

取余只能是整数,可以为正整数或负整数。在语句表达式余数符号前面的符号为正,余数为正整数;在语句表达式余数福海前面的符号为负,余数为负整数。
注释:printf("%%");//输出的%
int num; return((num>0)&&(num&(num-1))==0);//先判断数字是否为整数,之后判断“位与”实际为2进制的位与运算———(num&(num-1))==0),最后执行的是逻辑与。

不同长度的数据进行位运算

系统会自动将数据向高级的数据类型进行转换,如图。
从下往上转换

位与或和逻辑与或的区别

& 和 && 在判断语句中都可以实现“和”这个功能,不过区别在于 & 两边都运算,而 && 先算 && 左侧,若左侧为 false 那么右侧就不运算了。因此从效率上来说,判断语句中推荐使用 &&。
而 | 和 || 的比较与上类似,不做赘述。

猜你喜欢

转载自blog.csdn.net/qq_31932681/article/details/94363703