嗨翻C语言笔记(一)
对自己狠一点,逼自己努力,总有一天你会感谢今天的自己!
C语言不支持现成的字符串, 只能用数组表示.
& (and)运算, 即两个数的每个二进制位都进行比较, 对等位均为1时为1, 否则为0. 比如在计算机网咯笔记中有 ip和子网掩码对比获取子网 的印象过程中:
C 的数据类型
浮点型: float, double
整数型: char, int, short,long
[C中char以字符编码保存,比如a保存为 65 ]
所以 6 & 4 的结果是4, 这是怎么求得的呢?
6 转成二进制是 110
4 转成二进制是 100
两个数求 & 后的值是 100 转换成十进制就是4, 因此结果就是4.
printf() //用于格式化输出
%s : 字符串
%i : 整数
%p : 将地址以10禁止的格式输出
在C中指针的长度占用8个字节. (32位占4个字节,64位系统占8个字节)
* 运算符 和 &运算符的区别:
&
@1. 后接变量名,表取址运算符,用于获取该变量的内存地址
@2. 做二进制运算表 and 运算,用于返回两个比较数二进制对等位上同时为真的位, 比如 6 & 4 返回 4.
*
@1. 声明变量时加它仅表指针类型
@2.使用时在变量前加它,表取值运算符,用于获取该内存地址对应的值
因此
int *p; //声明时前面带 * , 进表示他是指针类型
*p = 5; //该指针p没有任何引用地址,就妄图赋值,报错的, 它是野指针, 必须先有内存地址后才能赋值.
int a = 10;
p = &a; //&a是取址,返回给p变量的是一个地址值,
*p = 14; //单个 *p 表取值, 整个表达式的意思是先取值然后给赋值14
再来深入理解下面的例子:
char a[] = "hello"; //实质上等于 char a[] = {'h', 'e', 'l', 'l', 'o'};
char *p;
p = &a; //p获得了字符串的第一个元素的地址
printf("p=%p\n", p);
printf("p+1=%p \n", (p+1) ); //打印第二个元素的地址
printf("*(p+1)=%c \n", *(p+1) ); //打印第二个元素的值, %c表字符, %s表字符串,不要用错.
输出为:
p = 0x7fff5a563786
p+1 = 0x7fff5a563787 86,87结尾充分说明一个字符占用一个字节
*(p+1)=e
上面字符串地址 p 和 p+1 只差一位,那是因为它是字符, 如果是整型,那么这个地址值就要差4位了, 看下面:
int a[] = {1,2,3,4};
int *p = NULL;
p = &a; //p获得了字符串的第一个元素的地址
printf("p=%p\n", p); //打印第一个元素的地址
printf("p+1=%p \n", (p+1) ); //打印第二个元素的地址
printf("*(p+1)=%d \n", *(p+1) ); //打印第二个元素的值
看输出:
p =0x7fff5fad8770
p+1=0x7fff5fad8774
*(p+1)=2
存储区的结构:
栈区 --局部变量
堆区
全局量区 --所有函数外,包括main函数
常量区域
代码段区域
14:38 冷水
vs 3. sizeof() 可用于获取变量的占用长度或类型长度
@1. 类型:
sizeof(int) ; //返回4, 表整型占用4个字节
@2.占用字节:
char b[] = "hello world";
printf("%d\n",sizeof(b) ); //使用数组变量名, 返回12,其中加空格是11个,最后一个 \o 数组结束符
@3. 指针类型
check(b); //输出8, 表指针的长度是八个字节
void check(char msg[]) {
//当参数传递的时候,用sizeof()把数组当成了第一个元素的指针地址[指针类型],因此输出的是指针的长度
printf("sizeof value:%d", sizeof(msg));
}
vs 4. 计算机会为字符串的每一个字符(包括空格)以及结束符\0 在栈上分配空间,并把首字符的地址和变量名关联起来, 只要出现这个数组变量名, 计算机就会把他替换成字符串首字符的地址,因此数组变量就好比一个指针.
printf("%s\n", b ); //输出 "hello world"; 当字符串
printf("%p \n", b); //输出 0x7fff5a63878 当地址
vs 5. 特殊的变量字符串 - 在C语言中字符串其实是char数组
char *cards = "jqk"; //"jqk"是存放在常量区的,