假定程序运行环境为VC6.0,缺省为四字节对齐,CPU(32小字节序处理器)
1.char x[]="ab0defg" char y[]={'a','b','0','d','e','f','g'} char *z=''ab0defg"
1)数组长度x大于y,x和z是8个元素,y是7个元素,x和z含'\0'
2)字符串长度,x和z是7,y是随机值,因为y没有'\0'
3)字节数,x是8,y是7,z是4
4)字符串中含整数零不算斜杠零
2.传数组名相当于传了数组首元素地址。
3.在一个函数内复合语句中定义的变量在本函数范围内无效,如
void test()
{
{
int i=0;
}
printf("%d\n",i);
}
4.'0'--48 '\0'--0 0--0 NULL--0
5.
void main()
{
union
{
short k;
char i[2];
}*s, a;
s = &a;
s->i[0] = 0x39;
s->i[1] = 0x38;
printf("%x\n", s->k);//如果是小端存储,此时输出的是3839,高次节序在低地址处
return 0;
}
6.
#define N 4
#define Y(n) ((N+2)*n)
z = 2 * (N + Y(5 + 1)); //Y(5+1)=((N+2)*n+1)
7.以指针作为入参,可以减少函数参数压栈的系统开销
8.
int main()
{
unsigned char a = 200;
unsigned char b = 100;
unsigned char c = 0;
c = a + b;
printf("%d %d\n", a + b, c); //需要整型提升,11001000+01100100 = 100101100 其结果是300,44
getchar();
return 0;
}
9.无名位段单独占一个字节
10.
int main()
{
char c;
unsigned char uc; //无符号,一个字节
unsigned short us;
c = 128; //00000000 00000000 00000000 10000000
uc = 128; //00000000 00000000 00000000 10000000
us = c + uc;
printf("0x%x\n", us); //数据溢出,整型提升,有符号补一,无符号补零,所以为0x0
us = (unsigned char)c + uc;
printf("0x%x\n", us); //都补零,只取前两个字节,所以为0x00000100
us = c + (char)uc;
printf("0x%x\n", us); //都补一,只取前两个字节,所以为0xffffff00
getchar();
return 0;
}
最后结果为0x0,0x100,0xff00
11.
int *sum(int a, int b)
{
int s = 0;
s = a + b;
return &s;
}
int main()
{
int a = 2;
int b = 3;
int *p = NULL;
p = sum(a, b);
printf("%d+%d=", a,b);
printf("%d\n", *p);
getchar();
return 0;
}
此程序的执行结果不确定,根据函数栈帧的原理,调用完函数sum,其被销毁,返回值保存在寄存器中,访问p中的内容时,其值或已被修改。
12.
unsigned short *puc[10][10];
typedef union un
{
unsigned long ul; //4
unsigned short u2[7]; //14
unsigned char uc; //1
}un_s;
int main()
{
un_s st, *pst;
printf("%d\n", sizeof(puc)); //一个指针数组,其存放地址,4*100=400
printf("%d\n", sizeof(st)); //又因为内存对齐,所以为最大对齐数的整数倍,16
printf("%d\n", sizeof(pst)); //地址,四个字节
printf("%d\n", sizeof(*pst)); //16
getchar();
return 0;
}
13.数组指针:int (*p)[4]=&arr
p是一个指针,该指针可以指向一个数组,数组有四个元素,每个元素是int*
14.
struct sb
{
long a1;
char a2;
char a3;
long a4;
long a5;
}*p; //大小为16个字节
p=(struct sb*)0x100000
p+0x1=100010 //偏移16个字节
(unsigned long)p+0x1=0x100001
(unsigned long*)p+0x1=0x100004
(char *)p+0x1=0x100001
对结构体指针加一,向后偏移一个结构;将结构体类型强制转换为长整型,向后加一;强制转化为指针,加一相当于加上数据类型的大小
15.枚举结构
enum A
{
X,
Y,
Z = 255,
A,
B,
};
X为0,Y为1,B为257,默认
0,1,2,3.....
16.在switch语句中,
没有break,直接跳转挨着执行下一条语句,知道遇到break.
17.
#pragma pack(4)
int main()
{
unsigned char puc[4];
struct pim
{
unsigned char uc1;
unsigned char uc2 : 1;
unsigned char uc3 : 2;
unsigned char uc4 : 3;
}*pst;
pst = (struct pim*)puc;
memset(puc, 0, 4);
pst->uc1 = 2; //10
pst->uc2 = 3; //11
pst->uc3 = 4; //100
pst->uc4 = 5; //101
printf("%02x %02x %02x %02x", puc[0], puc[1], puc[2], puc[3]);
getchar();
return 0;
}
1)%02x表示两个16进制位 2)VC6.0下位段是从后向前存储的,32位4字节存储 3)结构体大小为2字节,uc1占1个字节,uc2,uc3和uc4占1个字节 4)最后结果为02 29 00 00
![](https://img-blog.csdn.net/20170912224335116?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZ3Vvcm9uZzUyMA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
18.数组未初始化,其值都是随机值。
19.无符号的长整型,其值恒大于零。
20.一个指针需要接收函数调用的返回值,才能改变指针指向的内容。
21.unsigned char*只能访问一个字节,unsigned long*可以访问四个字节。
22.在函数调用中,应该传结构体类型的地址,而不应是值传递,形参是实参的一份临时拷贝,函数调用完会销毁。并且值传递的压栈开销比较大。
23.
char *p = NULL;
p[0] = 2;
printf("%d\n", *p);
空指针不能解引用。
24.进行动态内存分配的时候,一是要检测开辟是否失败,二是要进行内存的释放,防止发生内存泄漏。
#include <stdlib.h>
int main()
{
int *p = malloc(sizeof(int));
if (p == NULL)
{
perror("malloc");
exit(EXIT_FAILURE);
}
free(p);
p = NULL;
return 0;
}
25.不能返回栈空间的地址,因为函数调用完以后,栈空间的局部变量被销毁,如
char *test(void)
{
char p[] = "hello";
return p; //返回的是h的地址
}
26.
char* test(char *p)
{
p = (char*)malloc(100);
return p;
}
int main()
{
char *str = NULL;
str=test(str); //值传递,临时拷贝
strcpy(str, "hello");
printf(str);
free(str);
str = NULL;
getchar();
return 0;
}
打印hello,如果是值传递,调用函数应该有返回值。如果调用函数无返回值,应该传指针str的地址。
27.在释放动态开辟的内存的时候,如果指针不置空,str会变成野指针。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)