拾遗
1.static和const区别
const的意思是“常量”,也就是说变量一旦被定义就不能被修改,即是说变量是一个右值。
static的意思有两层。第一层是当它作用在函数名或者全局变量上时,这时static关键字会把这两者的extern链接属性修改为internal。第二层是当static作用在局部变量上时,存放这个局部变量的内存空间在被定以后就不会释放,哪怕重新定义这个变量也不行,直到程序结束内存才会释放。
2.左值和右值
定义:lvalue(locator value)代表一个在内存中占有确定位置的对象(换句话说就是有一个地址)。 rvalue通过排他性来定义,每个表达式不是lvalue就是rvalue。因此从上面的lvalue的定义,rvalue是在不在内存中占有确定位置的表达式。
根据以上定义,右值没有一个确定的内存空间与之对应,所以没有办法赋值。
3.链接属性和作用域的区别和联系
linkage是针对声明而言的,只有三种:
external,可以同时在多个文件中声明,表示同一个对象或函数
internal,可以在本文件中声明多次
none,只能声明一次
编译器确定标识符的 linkage 的时候会考虑到标识符所在的 scope ,但是和scope不是一回事。linkage不用多文件编译的话用不着。
4.函数可变参数
#include<stdio.h>
#include<stdarg.h>
void fun(int num, ...)
{
int i;
int res = 0;
va_list v1; //v1实际是一个字符指针,从头文件里可以找到
va_start(v1, num); //使v1指向可变列表中第一个值,即num后的第一个参数
printf("*v = %d\n",*v1);
for(i = 0; i < num-1; i++) //num 减一是为了防止下标超限
{
res = va_arg(v1, int); //该函数返回v1指向的值,并是v1向下移动一个int的距离,使其指向下一个int
printf("res = %d, *v1 = %d\n",res, *v1);
}
va_end(v1); //关闭v1指针,使其指向null
}
int main(void)
{
fun(4,1,2,3,4);
return 0;
}
这个函数简单的介绍了可变参数函数的用法。
首先,必须包含stdarg.h 头文件,我们用到的四个关键字或者函数,都在这个头文件中。
va_list
用于定义一个指向参数的指针,其实就是一个char* 的指针。
va_start(v1, num);
将v1指针指向可变参数的第一个参数。通过打印*v1可知,打印出来的是,1 ,正是第一个可变参数。
res = va_arg(v1, int);
这个函数返回v1指针所指的值,并使v1指针移动sizeof(int) = 4
, 个字节,使其指向下一个参数。以前一直以为当参数类型为char时,应该写char,但是今天实践了一下发现,当为char时系统会自动提升为int,当为float时自动提升为double, 字符串时为char * 。
va_end(v1);
最后一句,为了安全性,关闭v1指针,其实就是使v1为null。
————————————————
版权声明:本文为优快云博主「WitheredLotus」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/canhelove/article/details/83421134
5.typedef关键字
参考:https://www.cnblogs.com/aaronLinux/p/5769167.html
6.assert关键字
assert
宏的原型定义在<assert.h>
中,其作用是如果它的条件返回错误,则终止程序执行,原型定义:
#include <assert.h>
void assert( int expression );
assert
的作用是现计算表达式 expression
,如果其值为假(即为0),那么它先向stderr
打印一条出错信息,然后通过调用 abort
来终止程序运行。
7.关于修改指针的值
我们知道修改指针的值可以简单的通过为它赋值来实现,但有些情况下却不可以,比如说,当我们希望通过一个函数来修改指针的值,因为函数的局部变量都会被释放,在函数内部直接修改指针的值是没用的。但我们又知道,可以使用指针在函数中来修改一个变量的值。所以结论就是,当我们想要在函数中修改指针的值,办法就是,定义一个指向指针的指针,并把想要修改的指针的地址传入进去。一定要牢记,像指针,malloc函数这种直接操作内存的命令是与函数的作用域无关的!实例代码如下:
#include<stdio.h>
void change(int** p2)
{
int b = 6;
*p2 = &b;
}
int main(void)
{
int* p;
int a = 5;
p = &a;
change(&p);
printf("%d\n", *p);
return 0;
}
8.关于用指针在函数中来修改值
例子一:
int test(int* p)
{
*p = 5;
return 0;
}
int main()
{
int a,*p;
a = 0;
p = &a;
test(p);
printf("%d\n", a);
}
这个例子中,是可以成功修改a的值的。
例子二:
int test(int *p)
{
p = (int*)malloc(sizeof(int));
*p = 1;
return 0;
}
int main(void)
{
int *p = NULL;
test(p);
printf("%d\n",*(p+1));
return 0;
}
问题是,这个时候main函数里的p指向的值是多少?答案是NULL。在这里函数只是接受了NULL这个值而已,与上一个例子不一样的是,这个例子分配内存是在函数内进行的吗,而例一中int a就已经给a分配好了内存。