不正确的赋值或赋初值的方式是 char str[10];str="string"
cause:str是一个指针常量,要区分指针常量和指针变量,
指针常量是不可以被赋值和改变值的,这里“string”返回的是一个指针地址,
也就是连续空间的首地址,‘s’的地址。
str++ 也是不正确的,因为str是常量
逻辑运算 与(&),或(|),非(~),异或(^); 异或:相同为0,不同为1.
理解异或来交换两个整数:
a=x+y,
b=x+z;
a=a^b=y+z;//a与b不同的部分之和
b=b^a=x+y;//
a=a^b=x+z;//交换了数值
NULL=0,EOF=-1;
若变量已经正确定义,——不可以使指针p成为空指针
A:p=EOF; B:p=0; C:p='\0'; D:p=NULL
选择A
B,C,D在数值上都等于0
C语言中的NULL代表空指针,其定义为
#define NULL (void *)0
EOF是End Of File的简写,即文件结尾。其定义为
#define EOF -1
二者区别:
1 值不同,NULL是0, EOF是-1。
2 类型不同,NULL是指针,而EOF只是普通的整型常量。
3 应用范围不同。
NULL一般用作指针操作,包括指针类型赋初始值,返回指针类型的函数在出错时的返回值等。
EOF一般用于输入函数,比如scanf, 或者各种读文件操作函数等。当返回EOF时代表读函数出错,达到了文件尾。
sizeof(char*) 返回的是开始定义的的存储空间,要加1;而strlen(char*) 返回的是到第一个'\0'的字符个数。不加1。
测试如下:
#include
int main(void) {
// your code goes here
char *a="1234\0 12234";
int x=sizeof(a);
int b=strlen(a);
printf("%d %d",x,b);
return 0;
}
结果:8 4
char *a="zlz";
char b[5];
sizeof(a) = 8 ; // 64位系统,8代表的是指针的大小,指针占8字节
sizeof(b) = 5 ; // 计算字符串数组的结果是真实的字符数组大小
执行find -nx ould text.txt时,*++argv[1]的值
答案是:n
首先要明白argv[]是你所输入字符串的意思,
argv[0]或者argv是指你所输入的第一个字符串,
argv[1]是你所输入的第二个字符串,以此类推,
而++argv[1]就是你输入的第二个字符串的下一个字符的意思,
也就是“-nx”中的“n“,所以答案就是n
printf("%x\n",(0x19<<1)&0x17); 输出12 注意输出8进制的结果
~(~1<<1)=3
不正确的实型常量:
E3:(E之前无数字)
2.0E:无阶码
2.3E1.5:阶码必须是整数
小数部分要大于等于1,小于10.
a[-1]= 这个是有意义的, 而且有这样用的代码
比如我们都知道数组下表是从0开始的
那假如我们想从1开始怎么办
定义一个指针,指向a[-1]这个位置,
#include
void main(){
int a[] = {1,3,4};
int *p = &a[-1];
int i =0;
for( i = 1; i <4; i++){
printf("%d\n", p[i]);
}
}
1.因为数组并不检查下表是否越界
2.下表仅表示偏移, -1就表示第一个元素前面那个元素
单目运算符是指运算所需变量为一个的运算符,又叫一元运算符,
其中有逻辑非运算符:!、按位取反运算符:~、自增自减运算符:++, --等。
逻辑非运算符【!】、按位取反运算符【~】、自增自减运算符【++, --】、
负号运算符【-】、类型转换运算符【(类型)】、指针运算符和取地址运算符【*和&】、长度运算符【sizeof】
运算所需变量为两个的运算符叫做双目运算符。
例如+,-,*,/,%,<,>,>=,<=,==,!=,<<,>>,&,^,|,&&,||,=
运算所需变量为三个的运算符叫做三目运算符,只有条件表达式 A?B:C
int **p[10],p是一个数组,数组里存的元素是指向指针的指针。
int a=1;
int *b=&a;
int **c=&b;
int **p[10];
p[0]=c;
#include
void swap(int *a,int *b){
int *p;
p=b;
b=a;
a=p;
}
void main(){
int x=0,y=3;
swap(&y,&x); //传的是地址
printf("%d %d",x,y);}
输出结果是 0 3
注意,这里传的不是变量,而是指针常量 !!!!
///上面这个函数我们只是把x,y的地址复制给了a和b,
这个函数只是让a指向了y,b指向了x,是改变了a,b,但是和&x,&y无关;
而下面的函数中却交换了a,b指针(也就是&x,&y)指向的值,从而交换了&x,&y地址指向的值。
最本质的原因是:同一个地址可以有多个变量指向,
这些变量的唯一共同点是指向的地址是一样的,而且都可以改变地址指向的值。
(每个变量互不影响,除非哪个变量改变了地址指向的值)
正确的函数
方法一:void swap(int* x,int *y){ //注意和上面的区别
int t;
t=*x;
*x=*y; //看清楚这步的作用
*y=t;
}
方法二:传引用:
void swap(int &x,int &y){
int a=x;
x=y;
y=a;
}
int a[]={1,3,5,7,9};
int *b=a+2;
printf("%d ",*b++);
printf("%d",*b)
输出结果为 5 7
首先优先级上先是*,后++,所以等于(*b),这步输出后再b++,指向第三个数组元素;
tc
vc
ANSI标准定义int是占2个字节,TC是按ANSI标准的,它的int是占2个字节的。但是在VC里,一个int是占4个字节的
其他的都一样
char:1
short:2
long int:4 //long int 一定不低于int的字节数,看是32位还是64位的
float:4
double:8
long double:10
unsigned char a=0;
int b=1;
do{
b++;
a--
}while(a!=0)
变量b的值等于257;
分析:首先确定unsigned的取值范围是0-255;
0-1=255;
b=2,a=255;
b=3,a=254;
a=0;=254+3=257;
char a[]="ABC\\xyz\007\xFF";
sizeof(a)=10;
分析:\007表示八进制7,\xFF表示十六进制FF;
char a[10]={'A','B','C','\\','X','Y','Z','\007','\xFF','\0'};
\后面的数要么是八进制,要么是十六进制,不可以是十进制。
\101 --------------101是八进制
\x41 ---------------41是十六进制
注意char 取值范围是:[-128,127]
-0表示-128(特殊规定)
补码存储char
源码存储unsigned char
unsigned char 取值范围是:[0,255]
char a=-129;
printf("%d",a); //会输入多少?? 结果为 127 ,为什么呢?
char a=255;
printf("%d",a);
结果是-1
几个常识性的ASCII值
/
'\0'=0
'0'=48
'a'=97
'A'=65;
struct st{
char name[10];
int score;
}a[3],*p=a;
下列哪个用法是正确的(D)
A. p->name="name" //不可以这样赋值
B.*p.name='B' //首先.的优先级高于*;p.name表示的是一个字符数组指针,不可以这么赋值
C.(*p)->name[0]='c' //*p等价于a[0];这个引用结构体中的变量是用.而不是->;
D.*(*p).name='D'; //.的优先级大于*,所以这里等于name[0]='D';
关于字符串数组问题,在c语言中其实只存在字符串数组的概念,没有string的概念;
用string.h头文件中的strcpy函数来完成。
例如:
char a[10] = "123"; /*正确,在定义的时候初始化*/
char a[10];
a = "123"; /*错误,不能用“=”直接为字符数组赋值*/
strcpy(a, "123"); /*正确,使用strcpy函数复制字符串*/
比较也不能直接用=,而要用strcmp(char*,char*);
下列能使puts(s)语句正确的输出ABCDE字符串的程序段的是(C)
A.char s[5]={"ABCDE"};
B.char s[5]={'A','B','C','D','E'};
C.char *s;s="ABCDE";
D.char *s;scanf("%s",s);
char数组最后一位必须是'\0'作为结束符才能正常输出
这里C也反映了“ABCDE”的实质,就是返回一个字符指针而已;
至于D,因为这里s只是一个字符指针,读一个字符就结束了;
1. 表达式7<<1>>2^2的值为1
解析: 这里是从左往右依次计算的.
2.对于以下变量定义,表达式___不符合c语言语法
struct node{
int len;
char* pk;
}x={2,"right"},*p=&x;
A:p->pk; B:*p.pk; C:*p->pk; D:*x.pk
选择B;
这里间接引用 * 优先级低于.(取结构体和共用体的成员);而p是个指针变量,只能用->取结构体的成员
优先级:*小于.小于->
!!!!!
二维数组&&指针
a[i][j]=*(a[i]+j)=*(*(a+i)+j)
还要注意系统中的存储
对于结构体,它可能使用了多种数据类型,那么这句话翻译成对齐规则:
每个成员的起始地址 % 自身对齐值 = 0,如果不等于 0 则地址后移直到符合规则,
前面的补空达到对齐值。
换句话说,对于结构体而言,结构体在在内存的存放顺序用如下规则即可映射出来:
(一)单独的每个成员的起始地址 % 每个成员的自身对齐值 = 0,
如果不等于 0 就后移,前面补空使得每个成员内存块为结构体中最大的对齐值。
(二)结构体的长度必须为结构体的自身对齐值的整数倍,不够就补空字节。
举例:
typedef struct
{
char aa;
short ab;
char ac;
long ad;
}A;
sizeof(A) 结果为: 12 内存位置为: $*$$ $*** $$$$ 注意:每个成员首地址必须为自身对齐值的整数倍。
typedef struct
{
char aa;
short ab;
char ac;
long ad;
}B;
sizeof(B) 结果为:8 内存为 $$$$ $$$$
结论:空间大小和结构体中的数据元素顺序有关。
typedef struct
{
long ba;
short bb;
long bc;
char bd;
short be;
}B;
sizeof(B)结果为:16 内存位置为:$$$$ $$** $$$$ $*$$
typedef struct
{
char ca;
char cb;
short cc;
char cd;
short ce;
A cf;
char cg;
short ch;
long ci;
}C;
sizeof(C)结果为:28 内存位置为:$$$$ $*$$ $*$$ $*** $$$$ $*$$ $$$$
typedef struct{
char name[8];
char sex[5]}node;
sizeof(node)=13
typedef struct{ //和上面的对比
int b;
char name[8];
char sex[5]}node;
sizeof(node)=18;
exit(0):正常运行程序并退出程序;
exit(1):非正常运行导致退出程序;
return():返回函数,若在主函数中,则会退出函数并返回一值。
文件相关函数调用及返回值
fopen(FILE*,char*mode)
发生错误时返回值为0;
char ch=fgetc(FILE*);//fgets(char*,int n,FILE*)//注意最多只能读取n-1个字符,除非遇到\0
fputc(char ch,FILE*);//fputs(char*,FILE*)
fputc在正常调用时返回写入文件的字符的ASCII码值,出错时,返回EOF(-1)
fgetc在正常调用时返回所读取的一个字节。如果读到文件末尾或者读取出错时返回EOF(-1)。
fgets返回值:
1.成功,则返回第一个参数(字符串指针);
2.在读字符时遇到end-of-file,则eof指示器被设置,如果还没读入任何字符就遇到这种情况,则buf保持原来的内容,返回NULL;
3.如果发生读入错误,error指示器被设置,返回NULL,buf的值可能被改变
fputs返回值:
该函数返回一个非负值,如果发生错误则返回 EOF(-1)。
fprintf(FILE*,“格式控制字符串”,输出表)
fscanf(FILE*,"格式控制字符串",地址表)
fwrite(内存地址(指针),数据项大小,数据项个数,文件指针)
fread参数和fwrite一模一样
随机读写
rewind(文件指针):强制文件指针返回到文件头的位置
fseek(文件指针,long offset,int 起始点)
起始点一般有3种选择
0 SEEK_SET
1 SEEK_CUR
2 SEEK_END
ftell(文件指针):返回到文件头的偏移量。//一般用于返回文件的长度
feof(文件指针):结束时返回1,否则返回0;
fclose(文件指针):顺利执行时返回值为0,否则返回-1(EOF)
以a打开文件时,文件指针指向文件的最后位置!!!!!
真的是醉了
带头节点的单链表head指向头结点的意思就是head就是头结点的指针形式;*head就是头结点
不带头结点的单链表head指向第一个有效节点,也就是第一个有效节点的指针形式;
破案了。。
c语言中scanf(“%2d%*2d%2d”,&a,&b);若要输入123456789 则变量a和b分别为?
a=12,b=56;
scanf可以指定输入的宽度,比如scanf(“%2d",&a);就是把输入数据的前两位赋值给a。
scanf可以用“*”跳过指定的宽度,比如scanf(“%2d%*2d%2d”,&a,&b);
就是把输入数据的前两位12赋值给a,然后跳过34两位,最后把下面两位56赋给b。
scanf函数遇到空格和非法输入时结束,并且可以指定输入宽度。
fprintf(fp,"%3c",'1')
输入到文件中是_ _ 1,左边补齐2位空字符
已知char *t={"how","are","you"};
则t是(B)
A.指向“how”的指针变量
B.指向字符指针的指针常量
分析:数组名是常量。字符指针指向的是字符串
int i=0;
int j=(i++)+(++i)+(i++);// j=0+2+2
结果:i=3,j=4;
int i=0;
int j=(i++)+(++i); //j=0+2
结果:i=2,j=2
这种东西写出来是要被杀头的