******
%a,%A 读入一个浮点值(仅C99有效)
%c 读入一个字符
%d 读入十进制整数
%i 读入十进制,八进制,十六进制整数
%o 读入八进制整数
%x,%X 读入十六进制整数
%s 读入一个字符串,遇空格、制表符或换行符结束。
%f,%F,%e,%E,%g,%G 用来输入实数,可以用小数形式或指数形式输入。
%p 读入一个指针
%u 读入一个无符号十进制整数
%n 至此已读入值的等价字符数
%[] 扫描字符集合
%% 读%符号
##############################################
sizeof
是一个运算符,给出某个类型或变量在内存中所占据的字节数
sizeof(int) ‘返回4
sizeof(i) '返回4
sizeof(double) '返回8
#####################################
运算符&
scanf("%d",&i); 里的& //&就是获得地址
获得变量的地址,它的操作数必须是变量
int i; printf("%x",&i);
地址的大小是否与int相同取决于编译器
#include <stdio.h>
int main(void){
long long i=0;
int p;
p=(long long)&i; //int类型可能范围不够承当i的地址的长度
printf("0x%x\n",p);
printf("%p\n",&i);
printf("%lu\n",sizeof(int));
printf("%lu\n",sizeof(&i));
return 0;
}
####&不能取的地址
&不能对没有地址的东西取地址
例如 :
&(a+b)
&(a++)
&(++a)
数组的地址差距永远是4
#################################################
指针
就是保存地址的变量
int i;
int* p = &i;
int* p,q;
int *p,q;
只是给p定义为指针
#########################
作为参数的指针
void f(int *p);
在被调用的时候得到了某个变量的地址;
int i=0;f(&i);
在函数里面可以通过这个指针访问外面的这个i
##############################################
访问那个地址上的变量*
*是一个单目运算符,用来访问指针的值所表示的地址上的变量
可以做右值也可以做左值
int k=*p;
*p=k+1;
scanf(); ‘传入地址
##################################
传入函数的数组成了什么
函数参数表中的数组实际上是指针
sizeof(a)==sizeof(int*)
但是可以用数组的运算符进行运算
数组参数
以下四种函数原型是等价的:
int sum(int *ar,int n);
int sum(int *,int);
int sum(int ar[],int n);
int sum(int [],int);
数组变量是特殊的指针
数组变量本身表达地址,所以
int a[10];int *p=a; //无需用&取地址
但是数组的单元表达的是变量,需要用&取地址
a==&a[0]
*运算符可以对指针做,也可以对数组做:
*a=25;
实际上数组变量是const的指针,所以不能被赋值
#####################################################
数组就是一种特殊的指针,但对const指针的所有的操作都不一定都可以对数组变量做,
结果也可能不一致,所以只是可以看作,并不是就是
#######################################################
字符的输入和输出
大小写转换
'a'-'A'可以得到两段之间的距离
a+'a'-'A' 可以把一个大写字母变成小写字母
a+'A'-'a' 可以把一个小写字母变成大写字母
逃逸字符
\b 回去一格 让下一个输出 回去上一个位置
\" 双引号
\t 到下一个表格位
\' 单引号
\n 换行
\\ 反斜杠本身
\r 回车
##############################################################
数组变量是特殊的指针
数组变量本身表达地址,所以
int a[10];int *p=a; //无需用&取地址
a==&a[0]
[]运算符可以对数组做,也可以对数组做:
*a=25;
数组变量是const的指针,所以不能被赋值
a[]<==>int *const a=...
###
指针是const
表示一旦得到了某个变量的地址,不能再指向其他变量
###
转换
总是可以把一个非const的值转换成const的
###
const数组
const int a[]={1,2,3,4,5,6,};
数组变量已经是const的指针了,
这里的const表明数组的每个单元都是const int
所以必须通过初始化进行赋值
###
保护数组值
因为把数组传入函数时传递的是地址,所以那个函数内部可以修改数组的值
为了保护数组不被函数破坏,可以设置参数为const
int sum(const int a[],int length);
####################
¥##################
###################
动态内存分配
malloc()
#include<stdio.h>
#include<stdlib.h>
int main(void){
void *p;
int cnt=0;
while(p=malloc(100*1024*1024)){
cnt++;
}
printf("分配了%d00Mb的空间\n",cnt);
return 0;
}
查看申请到多少内存
free()
把申请得来的空间还给“系统”
申请过的空间,最终都应该要还
混出来的,迟早是要还的
只能还申请来的空间的首地址
常见问题
申请了没free—>长时间运行内存逐渐下降
free过了再free
地址变过了,直接去free
##############################################
putchar
int putchar(int c);
向标准输出写一个字符
返回写了几个字符,EOF(-1) 表示写失败
getchar
int getcahr(void);
从标准输入读入一个字符
返回类型是int是为了返回EOF(-1)
Windows—>Ctrl-Z
Unix—>Ctrl-D
###########################3
程序参数
int main(int argc,char const *argv[])
argv[0] 是命令本身
当使用Unix的符号链接时,反映符号链接的名字
###################################
strlen();
size_t strlen(const char *s);
返回s的字符串长度(不包括结尾的0)
#########
字符串查找字符
strchr(a,b); //in a found b
char *strchr(const char *s,int c);
char *strrchr(const char *s,int c); //反过来查找
返回NULL表示没有找到
查找第一个输入的之后的字符
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
char s[80],x;
scanf("%c\n",&x);
gets(s);
char *p=strchr(s,x); //在s中寻找第一个 输入的x
printf("%s\n",p);
}
查找第二个输入的之后的字符
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
char s[80],x;
scanf("%c\n",&x);
gets(s);
char *p=strchr(s,x); //在s中寻找第一个 输入的x
p=strchr(p+1,x); //to found next x
printf("%s\n",p);
}
输出输入字符前面的字符
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main(){
char s[80],x;
scanf("%c\n",&x);
gets(s);
char *p=strchr(s,x); //在s中寻找第一个 输入的x
char c=*p;
*p='\0';
char *t=(char*)malloc(strlen(s)+1);
strcpy(t,s);
printf("%s\n",t);
free(t);
}
字符串以 '\0' 结尾
即 将p指针找到的第一个 转换为'\0'
字符串中找字符串
char *strstr(const char *s1,const char *s2);
char *strcasestr(const char *s1,const char *s2); //忽略大小写进行查找