目录
2、getchar()、gets()、scanf%c与%s的使用
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)。
在计算机内部表示整型数据时,实际上很少使用原码形式存储。原因如下:
-
加减法不方便:在原码表示法中,两个整数的加法需要分别对它们的符号位和数值部分进行操作,这会使加法操作变得复杂,同时还需要特别处理相加后的进位,比较麻烦。而在补码表示法中,只需要对两个整数的数值部分进行简单的加法运算,不需要特别处理进位,更加方便和高效。
符号位是二进制数的最高位(最左边的位),用来表示整数的正负。如果符号位为0,则表示该整数为正数,如果符号位为1,则表示该整数为负数。
-
两个零的表示:在原码表示法中,一个数的正负取决于它的符号位,如果符号位为1,则表示负数,如果符号位为0,则表示非负数(即正数或0)。这样就会出现两个零的表示形式,即+0和-0,从而导致运算的不确定性。而在补码表示法中,不存在这个问题,只有一个零,即0的补码为全0,不需要特别处理。
-
统一性:补码表示法可以将加减法的操作统一起来,使得对于计算机内部而言,对于加法和减法的处理方式是一样的,只需要进行加法运算即可。这种统一性可以更加方便和高效地实现计算机中的算术运算。同时,补码的表示方式还可以方便地进行乘法和除法等运算。
反码:反码是一种表示有符号整数的方法,它与补码类似,都是在原码的基础上加以改进。反码是将正数的二进制表示保持不变,负数的二进制表示则是将其原码按位取反(即将0变为1,将1变为0),但不像补码一样再加1。反码虽然能够表示正负数,但在加减法运算上和补码相比显得复杂,而且存在-0的问题,因此通常不被计算机采用。
ASCII码:ASCII码是一种字符编码标准,它将每个字符都用唯一的一个7位二进制数来表示。ASCII码的编码方式与整型数据的存储方式无关,因此不能用来直接表示整型数据
9、static类型
在编程中,static
是一个关键字,用于声明变量和函数,其含义取决于上下文。下面是 static
声明的两种常见用法:
-
static
变量
在函数内部声明的 static
变量被称为静态局部变量。它们与普通局部变量不同,因为它们的生命周期延长到整个程序运行期间,并且只能在声明它们的函数内部访问。每次调用函数时,静态变量的值都保留在上一次调用时,而不是像普通局部变量一样在每次调用时重新初始化。
在全局作用域中声明的 static
变量被称为静态全局变量。它们与普通全局变量不同,因为它们的作用域仅限于声明它们的文件内部。这意味着,在另一个文件中不能通过外部链接引用它们。
-
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
的成员name
和age
。这里,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; }
需要注意的是,使用->
运算符时,左操作数必须是一个结构体指针,而不能是一个结构体变量。如果左操作数是一个结构体变量,应该使用.
运算符来访问结构体变量的成员。