C语言记录
格式化输出
%d————十进制有符号输出
%u————十进制无符号输出
%x————以十六进制表示的整数
%s————字符串. “hello world”
%c————单个字符. char set = ‘a’
%e————指数形式的浮点数
%f————float型浮点数
%lf————double型浮点数
%p————指针的值
位移
<<. 左移 ———只有逻辑左移,高位溢出,低位补零
1010 0110————— <<3———0011 0000
>> 右移分:逻辑右移、算数右移。
逻辑右移—高位补0,低位溢出
1010 0110————>>3———0001 0100
算数右移:
1010 0101 >> 3. —————这里最高位1是符号位,表示负数
- - - - - - - - - - - -
1111 0100
2. 无符号位,右移—————低位溢出,高符号位补0
0010 0101 >>3 —————这里最高位0是符号位,表示正数
- - - - - - - - - - - -
0000 0100
总结一下吧,逻辑移位,无论是左移还是右移都是一样的。算数移位却不是一样的,首先左移是没有算数移位的,其次算数右移,分有符号位的右移和无符号位的右移,但是它们是有共同点的,高位补位补的是符号位。
C语言的输入
int n; //声明一个变量
printf(“请输出一个数\n”); //这句话是一个提示
scanf(“%d”, &n); //scanf是输入的函数,%d的意思是输入一个有符号的整数,&n是取值的意思。
变量的存储类别
物理内存、 虚拟内存
堆———动态申请内存
栈———主要存放局部变量
静态全局区
-)未初始化的静态全局区
静态变量(定义变量的时候,前面需要加上static修饰),或全局变量,没有初始化
-)初始化的静态全局区
全局变量、静态变量、赋过初值的
-)代码区
存放代码
-)文字常量区
存放常量
-)概念——在函数外定义的变量
-)需要用static修饰,它限定了作用范围,只能在它定义的.c中有效
-)作用在函数中;初次调用赋予空间,再次调用不再赋值,也不释放空间
void fun()
{
static int num=3;
num++;
printf(“num=%d\n”,num);
}
int main()
{
a = fun();
printf(“第一次打印%d\n”,a);
b = fun();
printf(“第二次打印%d\n”,b);
c = fun();
printf(“第三次打印%d\n”,c);
}
防止头文件重复引用
# ifndef __fun_h__
# define __fun_h__
文件内容
# endif
define带参宏
# define df(a,b) (a*b)
Int main() {
int num;
num = df(2,4);
return 0;
}
-) 2替换a,4替换b
-)num = df(2+3,4) 2+3替换a,4替换b----> 2+3 * 4 = 2+12=14
制作静态库
-)gcc -c mylib.c -o mylib.o ————>>生成.o文件
-)ar rc libtestlib.a mylib.o ————>> 静态库起名的时候是以lib开头,.a结尾
-)是将mylib.c转换为静态库libtestlib.a,二进制
编译
-)gcc -static my_text.c libtestlib.a -o mytext
制作动态库
-)制作动态链接库
gcc -shared mylib.c -o libtestlib.so
-)动态库的使用
gcc mytest.c libtestlib.so. -o mytest
动态库与静态库的不同
-)静态库不仅包含代码的二进制还包含所需的库———>导致所占内存大
-)动态库与代码是对应的关系———>所占内存小
指针指向的数据类型来分
-)字符型指针
字符型数据的地址
char *p; //定义了一个字符变量指针,只能存放字符型数据的地址编号
- - - - - -
char ch;
p = &ch;
-)短整型指针
short int *p; //定义了一个短整型的指针变量p,只能存放短整型变量的地址
- - - - - - - -
short int a;
p = &a;
-)整型指针
int *p;
————
int a;
p = &a;
-)长整型指针
long int *p;
—————
-)float型指针
float *p;
- - - - -
float a;
p = &a;
-)double 型指针
double *p;
- - - - - - - -
double a;
p = &a;
-)函数指针
-)结构体指针
-)指针的指针
-)数组的指针
1)指针数组———首先是数组,元素是相同类型的指针变量
2)指针数组的定义:类型 * 数组名 [元素个数]———> int *p[10];
指针和变量的关系
-)指针可以存放变量的地址编号
引用变量
1)通过变量的名称引用
int a;
a = 100;
2)可以通过指针变量来引用变量
int *p;// *号表示或者修饰p是一个指针
p = &a; //取a的地址赋值给p,p保存了a的地址,或者p指向了a
*p = 100; // *+一个指针是取值的意思;*+p(指针变量)等价于指针指向的变量
- - - - - — - - - - - - - - - - - - - - - -
指针是可以初始化的
指针的运算
-)指针可以加一个整数,往下指几个它指向的变量,结果还是一个地址
int a[10];
int *p;
p =a;
p+2; //p是a[0]的地址,p+2是&a[2]。这里需要注明一下,为什么a表示的是a[0]的地址呢?因为a是一个数组,所以默认a表示a[0]的地址。
-)两个相同类型的指针可以比较大小
1)前提:类型相同;指针指向的是同一个数组中的地址
2)可以做减法————>减法的结果是指向中间的元素的个数,而不是指针类型的大小
-)相同类型的指针可以相互赋值
Int *p;
int *q;
int a;
p = &a; //这里是把a的地址赋值给了p
p = q; //q也是一个地址,p=q就是把p的地址赋给了q
字符串指针
—)比如 char *str[100]=“i love you”;
str[0] = “y”; //内容是可以修改的
- - - - - - - - - - - - - - -
char *str = “i love you”;
*str = y; //这是错误的,因为“i love you”存放在文字常量区,不可修改
- - - - - - - - - - - - - - -
char *str = (char*)malloc(10*sizeof(char));
strcpy(str,”i love you”);
*str = “y”; //正确,堆区的内容是可以修改的
-)可修改性
1)str指针指向的内存是否可以修改,要看str指向的是哪里?
2)str指向的是文字常量区,内存里的内容是不可以修改的
3)str指向的是栈、堆、静态全局区的时候,内存里的内容可以修改
-)初始化
字符数组、指针指向的字符串:定义时直接初始化
char buf_aver[] = “hello world”;
char *buf_point = “hello world”;
1)堆中存放的字符串,不能初始化,只能使用strcpy、scanf赋值
char *buf_heap;
buf_heap = (char*)malloc(15);
strcpy(buf_heap,”hello world”);
scanf(%s,”buf_heap”);
-)使用时赋值
字符数组:使用scanf、strcpy
buf_aver = “hello world”; //错误,buf_aver是buf_aver数组buf_aver的首地址,地址等于地址,除非地址指向的是内容。所以它是错误的。
strcpy(buf_aver,’hello world’); //正确
scanf(“%s”,buf_aver); //正确
指向字符串的指针:
buf_point = “hello kitty”; //正确
strcpy(buf_point,”hello kitty”); //错误,指针怎么复制呢?指针指向的内容才对,指针等于内容不对
数组指针也称行指针
数组指针和指针数组的区别 https://www.cnblogs.com/mq0036/p/3382732.html
-)定义
指向数组的类型 (*指针变量名)[指向的数组的个数]
int (*p) [5];//定义了一个数组指针变量p,p指向的是整型的有5个元素的 数组
p+1 往下指5个整型,跳过一个有5个整型元素的数组
-)例子
int a[3][5];
int (*p)[5];
printf(“a=%p\n”,a);//第0行的行地址
printf(“a=%p\n”,a+1);//第1行的行地址,a和a+1差20个字节
-)数组指针与指针数组
1)int (*p)[5];//数组指针
本身是一个指针变量,p占4个字节,用来保存数组的地址
2)int *p[5];//指针数组
本身是一个数组,是由5个int * 类型的指针元素构成的指针数组
多维数组中的指针的转换
int a[3][5];
a是第一行的指针,指向的是第一行
*a是第一行第一个元素的指针