#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
//结构体嵌套
struct stu
{
int num;
};
struct teacher
{
const char* name; //字符串指针
//char name[64];
int age;
stu t;
}t1;
void test()
{
//字符串指针指向字面常量
t1 = { "hello",18,{1} };
printf("姓名:%s 年龄:%d 学生学号:%d", t1.name, t1.age, t1.t.num);
//不可以修改指向的内容
//t1.name[0] = 'x'; //error
printf("\n");
//可以修改指针指向
t1.name = "你好";
printf("姓名:%s 年龄:%d 学生学号:%d", t1.name, t1.age, t1.t.num);
}
int main()
{
test();
return 0;
}
原因:字符串指针指向字面常量,字面常量不能修改,但可以修改指针指向,指向其他的字符串常量
解决方法1: 改成char name[64]
方法2:在堆区动态开辟一块内存,来通过字符串拷贝函数来拷贝常量区的字符串到堆区 注意:如果t1.name="hello"那么堆区存放的还是常量区字符串的地址,还是无法修改字符串的内容
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//结构体嵌套
struct stu
{
int num;
};
struct teacher
{
char* name; //字符串指针
int age;
stu t;
}t1;
void test()
{
t1.name = (char*)malloc(sizeof(char) * 64);
strcpy(t1.name, "hello");
printf("%s\n", t1.name);
t1.name[0] = 'x';
printf("%s\n", t1.name);
}
int main()
{
test();
return 0;
}
结构体创建在堆区
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
//结构体嵌套
struct stu
{
int num;
};
struct teacher
{
char* name; //字符串指针
int age;
stu t;
}*t1;
void test()
{
t1 = NULL;
//结构体创建在堆区
t1 = (teacher*)malloc(sizeof(teacher));
if (t1 == NULL)
{
return;
}
//清空结构体
memset(t1, 0, sizeof(teacher));
t1->age = 18;
t1->t.num = 1;
//下面这种写法是错误的,因为指针还没指向任意一块内存
//字符串拷贝函数是将一块内存上的字符串拷贝到另一块内存上
//也可以内存重叠拷贝
//无法将一块内存上的字符串地址赋值给指针
//strcpy(t1->name, "hello");
//所以虽然结构体在堆区开辟了一块内存,但是字符串指针只是在堆区找了一块内存存放了一个指针
//此指针并没有指向任何一块内存,所以需要再堆区再给它开辟一块内存,用来拷贝常量区的字符串到堆区,方便修改
t1->name = (char*)malloc(sizeof(char) * 64);
strcpy(t1->name, "hello");
t1->name[0] = 'x';
printf("%s", t1->name);
//堆区开辟的内存,手动释放
//要先释放年龄,再释放结构体本身
if (t1->name != NULL)
{
free(t1->name);
t1->name = NULL;
}
if (t1 != NULL)
{
free(t1);
t1 = NULL;
}
}
int main()
{
test();
return 0;
}
strcpy可以用sprintf函数代替