c语言小知识点小计
1、运算符的优先级
++
运算符的优先级是和指针解引用*
的优先级相同的,但在代码运行中执行顺序是从后往前
的。因此下面代码
int a[10] = {1,2,3,4};
int* arr = a;
printf("%d",*arr++);//访问的值是2
//注意:printf("%d",*a++);这种语法是错误的,因为a是个常量(指针常量),不可更改
2、 strcpy和memcpy的使用
strcpy只用于字符串数组之间的拷贝,因为strcpy是以\0
来判断结束的。使用方式如下:
char a[] = {"this is a test!"};
char b[100];
strcpy(b,a);//不像memcpy需要用户确定拷贝的大小,strcpy以'\0'为结束符判断拷贝的结束
memcpy()能够拷贝任意类型的数组,但需要手动确定拷贝的大小
int a[10] = {1,2,3,4,5};
int b[10];
strcpy(b,a,sizeof(a));//memcpy()需要手动确定拷贝数据的大小
3、数组和数组的首地址
由于数组名是一个指针常量,因此指针的指向是不能更改的,也就是说数组名的指向的地址是不能更改的。因此不能有数组名++
的操作如下图代码:
int a[10] = {1,2,3,4} ;
//a++这种写法是错误的,当需要对数组的元素进行访问时,
//可以用下标或者是重新定义一个指针来对数组进行访问。如下所示:
//方法一
for (int i = 0;i<10;i++)
{
printf("数组中的元素是%d",a[i]);
}
//方法二
int *arr = a;
for(int i = 0;i<10;i++)
{
printf("数组中的元素是%d",*arr+i)
}
4、sizeof()的使用
sizeof可以获取当前变量的大小,如下面示例所见:
int arr[10] = {1,2,3,4};
pirnft("数组的大小是%d",sizeof(a));//获取的是10个int数据占据的空间大小
printf("数组指针的大小是%d",sizeof(&a);//获取的是指针的大小
5、指向常量和常量指针
所谓的常量指针
是指常量的值不能通过指针来修改,但指针的指向是可以修改的;
所谓的指针常量
是指指针的指向不可修改,在第一次绑定赋值后就不能在去绑定其他变量了。示例如下:
//指针常量
int b1 = 10;
int *const ddd = &b1; // 指针常量,指针的指向不能更改,需在初始化的时候就赋值
//ddd = &c1;错误,因为指针常量的指向是不能修改的
*ddd = 20;//语法正确
//常量指针
const int *ccc;
int c1 = 20;
int d1 = 30;
ccc = &c1;
ccc = &d1;
// *ccc = 40;语法错误,常量指针不能用过指针来修改变量的值,当可以修改指向
cout << "数组的大小是:" << *ccc << endl;
6、不同系统中变量的大小
- 在32位系统中指针的大小占
4字节:32位
- 在64位系统中指针的大小占
8字节:64位
- char———1字节
short———2字节
int————4字节
long————4字节
long long——8字节
float————4字节
double———8字节
7、c语言中局部变的内存分配
局部变量在函数执行时在栈区分配空间,并在函数执行结束后释放空间。
8、结构体的内存大小与字节对齐
#include<stdio.h>
struct S1
{
char a;
int b;
char c;
};//占12字节
struct S2
{
int a;
char b;
int c;
char d;
};//占16字节
int main()
{
// sizeof()功能:获取了数据在内存中所占用的存储空间,以字节为单位来计数。
printf("%d\n", sizeof(struct S1));
printf("%d\n", sizeof(struct S2));
return 0;
}
- 这里可能不好理解在此对其进行解释(
假设为32位系统,因此当有跨字节时进行4字节对齐
):下图中每个框代表一个字节,由于ch占一个字节因此将其方到第一字节处。由于int 占4字节跨字节了,因此进行4字节对齐。short占2个字节因此放到后面的地址空间。由于char占一个字节没跨字节不用字节对齐。
内存对齐的规则:
9、数组和指针的区别
- char arr1[] = “hello”;和char *arr2 = “hello”;两句代码中出现的字符串都存储在静态存储区中。
- char arr1[] 声明了一个名为 arr1 的字符数组,这个数组的大小正好能够存放字符串 “hello” 加上一个结尾的空字符 ‘\0’。编译器会为 arr1 在栈上分配足够的空间,以存储所有这些字符。
- 字符串字面量 “hello” 存储在程序的常量区。
在函数执行时,“hello” 的内容会被复制到新分配的栈空间中,也就是 arr1 数组中。
这通常是通过一个循环来完成的,每个字符(包括结尾的空字符 ‘\0’)都会从常量区复制到 arr1 的相应位置。
int main()
{
char arr1[] = "hello";
char *arr2 = "hello";
arr1[0] = 'A';//这种写法没有问题,因为arr1是存放在栈上的变量。
printf("%c\r\n",arr1[0]);
//arr2[0] = 'A';这种写法是错误的,因为arr2是指向静态存储区的一个常量指针,不能用过指针来修改值,而且“hello”存放在静态存储区,里面的值就是不能进行修改的
printf("%c\r\n",arr2[0]);
}