c语言复习二之大杂烩

目录

1、赋值运算符=与关系运算符==的区别

2、getchar()、gets()、scanf%c与%s的使用

3、数组名

4、指针数组与数组指针

5、枚举类型值赋值给枚举类型

6、&、^、<<使用区别

7、逻辑与运算的短路特性

8、整型数据为什么以补码的形式存放

9、static类型

10、存储类型变量

11、寄存器变量

12、extern

13、结构体的嵌套


1、赋值运算符=与关系运算符==的区别

第2题while(k=1),=是赋值,相当于while(1),所以执行无限次

2、getchar()、gets()、scanf%c与%s的使用

getchar()输入一个字符,gets()可以输入字符串,但是没有gets(s1,s2);的写法

应该表示为gets(s1);get(s2);

3、数组名

数组名是一个常量指针(指向数组的第一个元素),表达式必须为可修改的左值

char s[100]; 不能s++ 因为s是常量

4、指针数组与数组指针

指针数组:元素为指针的数组 如int *p[2] 一个数组中的所有元素保存的都是指针

数组指针:元素为数组的指针 如int (*p)[2] 指向一个数组的指针

*p2='\0'; 表示在字符数组 b 的末尾插入一个字符串结束标志 '\0',表示该字符串的结束位置

*p2 = *p1; 把p1的值赋给p2

5、枚举类型值赋值给枚举类型

如果将枚举类型的第一个变量置为1, 则后面的依次为2, 3, 4, 5

6、&、^、<<使用区别

1、按位与运算符 & 是一个二元运算符,用于对两个二进制数的每一位进行比较,如果相应的两位都为 1,则结果的相应位为 1,否则为 0。

2、按位异或^:按位异或运算符用符号“^”表示,其作用是将两个操作数的每一个二进制位进行异或运算,当两个二进制位相同时,结果为0,否则为1。例如,二进制数1101 ^ 1010 = 0111,即13 ^ 10 = 7。

3、左移运算符:左移运算符用符号“<<”表示,其作用是将一个二进制数向左移动若干位。例如,二进制数1010 << 2 = 101000,即10左移两位后等于40。在左移运算中,左侧的操作数为需要移位的二进制数,右侧的操作数为需要左移的位数。

char a = 3, b = 6, c; c = a ^ b << 2; c的二进制是多少

错误点:优先级。b << 2 会先被计算

7、逻辑与运算的短路特性

a=5,b=6,c=7,d=8,执行(m=a>b)&&(n=c>d)后,n的值为多少

因为逻辑与运算的短路特性,只有当前面的表达式运算为真时才会继续计算后面的表达式。

8、整型数据为什么以补码的形式存放

在补码表示法中,正数的二进制表示和其原码相同,而负数的二进制表示是将其原码按位取反(即将0变为1,将1变为0),然后再加1。这种方式下,补码表示法中的符号位为1时,表示的是负数,符号位为0时,表示的是非负数(即正数或0)。

在计算机内部表示整型数据时,实际上很少使用原码形式存储。原因如下:

  1. 加减法不方便:在原码表示法中,两个整数的加法需要分别对它们的符号位和数值部分进行操作,这会使加法操作变得复杂,同时还需要特别处理相加后的进位,比较麻烦。而在补码表示法中,只需要对两个整数的数值部分进行简单的加法运算,不需要特别处理进位,更加方便和高效。

    符号位是二进制数的最高位(最左边的位),用来表示整数的正负。如果符号位为0,则表示该整数为正数,如果符号位为1,则表示该整数为负数。
  2. 两个零的表示:在原码表示法中,一个数的正负取决于它的符号位,如果符号位为1,则表示负数,如果符号位为0,则表示非负数(即正数或0)。这样就会出现两个零的表示形式,即+0和-0,从而导致运算的不确定性。而在补码表示法中,不存在这个问题,只有一个零,即0的补码为全0,不需要特别处理。

  3. 统一性:补码表示法可以将加减法的操作统一起来,使得对于计算机内部而言,对于加法和减法的处理方式是一样的,只需要进行加法运算即可。这种统一性可以更加方便和高效地实现计算机中的算术运算。同时,补码的表示方式还可以方便地进行乘法和除法等运算。

反码:反码是一种表示有符号整数的方法,它与补码类似,都是在原码的基础上加以改进。反码是将正数的二进制表示保持不变,负数的二进制表示则是将其原码按位取反(即将0变为1,将1变为0),但不像补码一样再加1。反码虽然能够表示正负数,但在加减法运算上和补码相比显得复杂,而且存在-0的问题,因此通常不被计算机采用。

ASCII码:ASCII码是一种字符编码标准,它将每个字符都用唯一的一个7位二进制数来表示。ASCII码的编码方式与整型数据的存储方式无关,因此不能用来直接表示整型数据

9、static类型

在编程中,static 是一个关键字,用于声明变量和函数,其含义取决于上下文。下面是 static 声明的两种常见用法:

  1. static 变量

在函数内部声明的 static 变量被称为静态局部变量。它们与普通局部变量不同,因为它们的生命周期延长到整个程序运行期间,并且只能在声明它们的函数内部访问。每次调用函数时,静态变量的值都保留在上一次调用时,而不是像普通局部变量一样在每次调用时重新初始化

在全局作用域中声明的 static 变量被称为静态全局变量。它们与普通全局变量不同,因为它们的作用域仅限于声明它们的文件内部。这意味着,在另一个文件中不能通过外部链接引用它们

  1. static 函数

在函数声明中使用 static 关键字可以将函数声明为静态函数。这意味着该函数仅在声明它的文件中可见,其他文件无法引用它。静态函数通常用于实现文件本地函数或库中的私有函数,以便隐藏实现细节并避免命名冲突。

10、存储类型变量

存储类型的变量在未赋值时,其值是不确定的(一般情况)。

需要注意的是,对于某些特定类型的变量(如指针),其未初始化时的值可能是空指针(NULL),这是一个特殊的值,表示该指针不指向任何有效的内存地址

11、寄存器变量

在C语言中,可以使用关键字"register"来声明一个变量为寄存器变量。例如:

register int i;

需要注意的是,使用关键字"register"只是对编译器提供了一个建议,表明该变量可以存储在寄存器中,但并不保证编译器一定会将其存储在寄存器中。这是因为寄存器数量有限,编译器可能会根据实际情况来决定哪些变量可以存储在寄存器中,哪些不能。

另外,需要注意的是,寄存器变量不能使用取地址符"&",因为寄存器没有地址。例如,下面的代码是不合法的:

register int i;
int *p = &i; // 错误,不能对寄存器变量取地址

无论变量是否声明为register,它们都可以在函数内部和外部定义。但是,定义为register的变量只能在函数内部使用,因为它们被存储在寄存器中,而寄存器是由编译器分配的。在函数外部定义register变量是无效的,因为变量无法被存储在寄存器中。

12、extern

external不是关键字

在C语言中,"extern"是一个关键字,用于声明一个变量或函数是在其他文件或模块中定义的,可以在当前文件或模块中引用。

如在main.c文件中定义全局变量

int main(){  
  int g_var = 0;
}

在other.c文件中声明该全局变量:

extern int g_var;

13、结构体的嵌套

结构体类型的成员也可以是另一个结构体类型的变量.

struct Date {
    int year;
    int month;
    int day;
};
​
struct Person {
    char name[20];
    int age;
    struct Date birth;
}

结构体在定义的时候就已经分配了空间,而不是在赋值的时候。

通过使用->运算符,访问了指针ptr所指向的结构体变量p的成员nameage。这里,ptr->name(*ptr).name是等价的,都可以用于访问结构体变量的成员。

struct Person {
    char name[20];
    int age;
};
​
int main() {
    struct Person p = {"Tom", 20};
    struct Person *ptr = &p;
    printf("Name: %s\n", ptr->name); // 使用->运算符访问name成员
    printf("Age: %d\n", ptr->age); // 使用->运算符访问age成员
    return 0;
}

需要注意的是,使用->运算符时,操作数必须是一个结构体指针,而不能是一个结构体变量。如果左操作数是一个结构体变量,应该使用.运算符来访问结构体变量的成员。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值