结构体:
fgets()
该函数是一个文件操作相关的函数
暂时使用这个函数可以从键盘商接收一个字符串,保存到数组中
原来接收字符串保存到数组中的方法
char str[50];
1) scanf("%s",str); //缺点:不能接收空格
2) gets(str); //优点:可以接收空格
//会有一个警告,不安全的
//不安全:比如数组长度是50,如果我们输入的
//的长度正好是50个,此时把50个字符全部存到
//数组中,存在问题 因为没有空间存放字符串结束符
fgets()是一个安全的字符串接收的函数
char ch[5]; //如果使用fgets此时数组中最多存放4个可见字符
//会自动的把数组的最后一个元素存放\0
fgets()使用格式:
fgets(数组名,数组长度,stdin);
fputs();也是一个文件操作相关的函数
格式:
fputs(数组名,stdout);
实例操作:
#include <stdio.h>
#include <string.h>
int main(int argc, const char * argv[]) {
char ch[5];
//fgets从输入缓冲区读取一个字符串保存到字符数组中
//当输入的字符串的长度大于数组的长度,此时fgets会自动的
//把数组的最后一个元素变成\0
//当输入的字符串的长度小于数组长度的时候,fgets还会接收回车
fgets(ch, sizeof(ch), stdin);
//去掉多余的\n
if(ch[strlen(ch)-1]=='\n') ch[strlen(ch)-1]='\0';
//上面那句话的意思是将数组ch的第strlen(ch)-1个元素改为\0;
//\n 它的ascii码值10
for (int i=0; i<5; i++) {
printf("%d\t",ch[i]);
}
//fputs是不会自动换行
//fputs也不能进行格式化的输出
//puts 可以自动换行
fputs(ch, stdout);
//printf("--->%s\n",ch);
return 0;
}
const :是一个类型修饰符;
const使用的地方:
1:修饰变量
例如:int a = 10; a = 200 ;此时打印出来a的值就会是200;如果
const int a = 10;此时在给a赋值 a= 200;就无法修改了;值还是10
但是如果 我写 int *p = &a;*p = 200 我打印*p的值就可以知道*p是200 但是a的值没变还是10;无解。。。。
修饰指针:分为三种情况
int a = 10;
int b = 20;
//定义个指针变量,p指向a
//此处的const的作用是指针变量p的指向可以改变,但是指向的变量的值
//不能改变的
1、const修饰的指针变量指向可变,指向的变量的值不可变
const int *p = &a; //给p初始化
p = &b; //重新修改了p的指向
//*p = 1000;
int const *p1 = &a;
p1 = p; //p1的指向也是可以改变
*p1 = 100; p1指向的变量的值是不能改变的
2、const修饰的指针变量,指针变量指向的变量值可以变,指向不能变
int * const p2 = &a;
*p2 = 2000; //值可以改变
//p2 = &b; //p2的指向不能变
3、const修饰的指针变量的指向和值,都不能改变
const int * const p3 = &a;
p3 = &b; //只想不能变
*p3 = 100; //指向的变量的值也不能变
记忆技巧:
看 const 和 * 的位置
如果 const 在 * 的左侧 表示指针变量指向的变量的值不能变,但是指向可以改变
const int *p = &a;
如果 const 在 * 的右侧 表示指针变量指向的变量的值可改变,但是指向不可以改变
int * const p=&a;
如果 const 出现在 *的两侧,表示指针变量的指向和值都不能改变
const int * const p=&a;
内存分区:栈区 :用户存放程序临时创建的局部变量;
堆区 :动态分配的内存段
bss段:存放未初始化的全局变量和静态变量;
数据段:存放已初始化的全局变量和静态变量和字符串常量等;
代码段:存放程序执行代码的一块区域;
/*
C语言中提供了3个动态内存分配函数:
1)malloc 函数
格式: void * malloc(unsigned size);
从内存的堆区分配大小为size个字节的连续的内存空间
如果内存分配成功 返回内存的首地址
失败 NULL
*/
#include <stdio.h>
#include <stdlib.h>
/**
* malloc函数的使用
*/
void test1(){
//从内存中申请一块内存空间,可以存储4个整数
// = 赋值,要求等号的左右两侧的类型要一致
//p中存放的事新申请的内存空间的首地址
//注意:malloc 申请的内存空间,如果我们不赋值?
// 是垃圾数
int *p = (int *)malloc(4*sizeof(int)); //16个字节,这里的int*是强制转换malloc为整型的指针变量
//使用一个函数给malloc申请的空间进行初始化
memset(p,'a',16);
if (p!=NULL) {
//申请成功做的事情
// *p = 10;
// *(p+1) = 100;
// *(p+2) = 1000;
// *(p+3) = 10000; //存放4个整数
}else{
//内存申请失败
printf("内存申请失败!\n");
}
for(int i=0;i<4 ;i++){
printf("%c\t",*(p+i));
}
}
void test2(){
//calloc 分配指定块数和长度的内存空间
//格式:calloc(块数,长度)
//分配了4块,每一块内存长度为4的内存空间
//他们的地址也是连续的
//注意事项:
//calloc 它使可以帮我们自动的初始化为0
int *p = (int *)calloc(4, sizeof(int)); //16个字节
if (p!=NULL) {
//申请成功做的事情
*p = 10;
*(p+1) = 100;
*(p+2) = 1000;
*(p+3) = 10000; //存放4个整数
}else{
//内存申请失败
printf("内存申请失败!\n");
}
for(int i=0;i<4 ;i++){
printf("%d\t",*(p+i));
}
}
int main(int argc, const char * argv[]) {
int *p = (int *)malloc(4*sizeof(int)); //16个字节
printf("old %p\n",p);
//realloc 函数可以给已经存在的空间扩充大小
p = realloc(p, 40*sizeof(int));
printf("new %p\n",p);
//40个内存空间
if (p!=NULL) {
//申请成功做的事情
*p = 10;
*(p+1) = 100;
*(p+2) = 1000;
*(p+3) = 10000; //存放4个整数
*(p+39)= 1;
printf("%d\n",*(p+39));
}else{
//内存申请失败
printf("内存申请失败!\n");
}
for(int i=0;i<4 ;i++){
printf("%d\t",*(p+i));
}
return 0;
}
free(要释放的空间的首地址)函数:释放动态申请的空间 ;
//free(p)以后,p是一个野指针,所以给它赋值一个null;
p = NULL;
指针函数:
返回值是指针的函数
指针函数的定义
指针类型 * 函数名(){
return 地址;
} |
|